I've got a ruby 2.0.0 and rails 4.0.0 app that has a 'Guitar' and 'Photos' model. I've used paperclip to upload a single file in Rails3, but am new to uploading multiple files in Rails 4. I created the second model to hold said photos, and read up on strong parameters, etc. I'm getting an error when attempting to add 3 photos to a guitar. In the logs: "Unpermitted parameters: photos_attributes". I've tried adding photos_attributes to the whitelist and no joy. I'm pulling my hair out here - there's no error in the web view, but when I console in and type 'Photo.all', I get nothing. What am I doing wrong? I'm kind of a newbie, please be gentle.
guitar.rb
class Guitar < ActiveRecord::Base
belongs_to :user
has_many :photos
accepts_nested_attributes_for :photos
end
photo.rb
class Photo < ActiveRecord::Base
belongs_to :guitar
has_attached_file :photo, styles: {
thumb: '100x100>',
square: '200x200#',
medium: '300x300>',
large: '600x6003'
}
end
guitars_controller.rb
class GuitarsController < ApplicationController
before_action :set_guitar, only: [:show, :edit, :update, :destroy]
# GET /guitars
# GET /guitars.json
def index
@guitars = Guitar.all
end
# GET /guitars/1
# GET /guitars/1.json
def show
end
# GET /guitars/new
def new
@guitar = current_user.guitars.build
3.times {@guitar.photos.build}
end
# GET /guitars/1/edit
def edit
3.times {@guitar.photos.build}
end
# POST /guitars
# POST /guitars.json
def create
@guitar = current_user.guitars.build(guitar_params)
respond_to do |format|
if @guitar.save
format.html { redirect_to @guitar, notice: 'Guitar was successfully created.' }
format.json { render action: 'show', status: :created, location: @guitar }
else
format.html { render action: 'new' }
format.json { render json: @guitar.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /guitars/1
# PATCH/PUT /guitars/1.json
def update
respond_to do |format|
if @guitar.update(guitar_params)
format.html { redirect_to @guitar, notice: 'Guitar was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @guitar.errors, status: :unprocessable_entity }
end
end
end
# DELETE /guitars/1
# DELETE /guitars/1.json
def destroy
@guitar.destroy
respond_to do |format|
format.html { redirect_to guitars_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_guitar
@guitar = Guitar.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def guitar_params
params.require(:guitar).permit(:make, :model, :year, :color, :serial, :price, :condition, :kind, :bodykind, :frets, :oneowner, :user_id, :description, :photos_attributes)
end
end
views/guitar/_form.html.erb
<%= form_for @guitar, :html => { :multipart => true } do |f| %>
<% if @guitar.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@guitar.errors.count, "error") %> prohibited this guitar from being saved:</h2>
<ul>
<% @guitar.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :make %><br>
<%= f.text_field :make %>
</div>
<div class="field">
<%= f.label :model %><br>
<%= f.text_field :model %>
</div>
<div class="field">
<%= f.label :year %><br>
<%= f.text_field :year %>
</div>
<div class="field">
<%= f.label :color %><br>
<%= f.text_field :color %>
</div>
<div class="field">
<%= f.label :serial %><br>
<%= f.text_field :serial %>
</div>
<div class="field">
<%= f.label :price %><br>
<%= f.text_field :price %>
</div>
<div class="field">
<%= f.label :condition %><br>
<%= f.number_field :condition %>
</div>
<div class="field">
<%= f.label :kind %><br>
<%= f.text_field :kind %>
</div>
<div class="field">
<%= f.label :bodykind %><br>
<%= f.text_field :bodykind %>
</div>
<div class="field">
<%= f.label :frets %><br>
<%= f.text_field :frets %>
</div>
<div class="field">
<%= f.label :oneowner %><br>
<%= f.check_box :oneowner %>
</div>
<div class="field">
<%= f.label :extended_description %><br>
<%= f.text_area :description %>
</div>
<%= f.fields_for :photos do |builder| %>
<%= builder.label :photo, "Image File" %>
<%= builder.file_field :photo %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
db/schema.rb
ActiveRecord::Schema.define(version: 20131014195859) do
create_table "guitars", force: true do |t|
t.string "make"
t.string "model"
t.string "year"
t.string "color"
t.string "serial"
t.string "price"
t.integer "condition"
t.string "kind"
t.string "bodykind"
t.string "frets"
t.boolean "oneowner"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "description"
end
add_index "guitars", ["user_id"], name: "index_guitars_on_user_id", using: :btree
create_table "photos", force: true do |t|
t.integer "guitar_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "photo_file_name"
t.string "photo_content_type"
t.integer "photo_file_size"
t.datetime "photo_updated_at"
end
create_table "users", force: true do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
t.string "city"
t.string "state"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
end
See Question&Answers more detail:
os