Rails 4: Multiple image upload using paperclip - ruby-on-rails

I'm looking to upload multiple images to my 'locations' model. I've called the images model 'assets'. One location has multiple assets. I'm also using paperclip to handle the uploads and nested_form to allow selecting multiple assets.
Weirdly, the locations hash looks to be passing the variables correctly, but they don't appear to be being picked up by the assets model. Any help would be great!
Location model
class Location < ActiveRecord::Base
has_many :location_post
has_many :posts, :through => :location_post
has_many :assets, dependent: :destroy
attr_accessor :asset, :assets_attributes
accepts_nested_attributes_for :assets, :allow_destroy => true
end
Asset model
class Asset < ActiveRecord::Base
belongs_to :location
has_attached_file :asset,
:styles => {
:blurred => "600x300^",:large => "600x600>", :medium => "250x250^" , :thumb => "100x100^"},
#:source_file_options => {:all => '-rotate "-90>"'},
:convert_options => {
:all => '-auto-orient', :blurred => "-blur 0x6 +repage -resize 600x300^"
},
:storage => :s3,
:s3_credentials => "#{Rails.root}/config/s3.yml",
:bucket => "[bucketname]",
:path => "/:style/:id/:filename"
validates_attachment_content_type :asset, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
end
Locations Controller
class LocationsController < ApplicationController
...
def new
#location = Location.new
#location.assets.build
#georesult = Geocoder.search(params[:query])
end
def create
#location = Location.find_or_create_by(name: location_params[:name])
respond_to do |format|
if #location.save
format.html { redirect_to #location, notice: ' <borat voice> Great success! </borat voice>' }
format.json { render :show, status: :created, location: #location }
else
format.html { render :new }
format.json { render json: #location.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /locations/1
# PATCH/PUT /locations/1.json
def update
respond_to do |format|
if #location.update(location_params)
format.html { redirect_to #location, notice: 'Location was successfully updated.' }
format.json { render :show, status: :ok, location: #location }
else
format.html { render :edit }
format.json { render json: #location.errors, status: :unprocessable_entity }
end
end
end
...
private
# Use callbacks to share common setup or constraints between actions.
def location_params
params[:location].permit(:name, :notes, :longitude, :country, :latitude, :query, assets_attributes: [ :asset, :asset_content_type, :asset_file_name, :tempfile, :asset_file_size, :asset_updated_at, :_destroy])
end
end
Form View
<%= nested_form_for(#location, :html=> {:multipart => true}) do |f| %>
...
<%= f.fields_for :assets do |a| %>
<%= a.file_field :asset %>
<%= a.link_to_remove "Remove this image" %>
<% end %>
<%= f.link_to_add "Add an image", :assets %>
...
<%= f.submit "Submit", :class => "btn btn-success submit_location" %>
<% end %>
Log output
Processing by LocationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"n4spoLjq4B3sZSJjqsGFRVjkseOwGgvquAHATBRG1Nk=", "location"=>{"name"=>"York", "notes"=>"", "lat
itude"=>"53.96230079999999", "longitude"=>"-1.0818844", "country"=>"", "assets_attributes"=>{"0"=>{"asset"=>#<ActionDispatch::Http::UploadedFile
:0x007ff739b7bb68 #tempfile=#<Tempfile:/var/folders/sc/gps8hkgj7yg31j81gpnfg9h00000gn/T/RackMultipart20140706-43312-kdpghs>, #original_filename=
"78509.max1024.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"location[assets_attributes][0][asset]\"; filen
ame=\"78509.max1024.jpg\"\r\nContent-Type: image/jpeg\r\n">, "_destroy"=>"false"}}}, "commit"=>"Submit", "id"=>"240"}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
Location Load (0.4ms) SELECT "locations".* FROM "locations" WHERE "locations"."id" = $1 LIMIT 1 [["id", 240]]
(0.2ms) BEGIN
(0.3ms) COMMIT
Redirected to http://localhost:3000/locations/240
Completed 302 Found in 9ms (ActiveRecord: 1.6ms)

I see couple of problems in your code:
First thing, you need to remove the following line from Location model:
attr_accessor :asset, :assets_attributes
as its making asset and asset_attributes as virtual attributes which is why they are not saved in database. Also, you don't need asset attribute in Location model as its been taken care by Asset model.
Then, update the location_params as suggested by #Pavan:
def location_params
## Use `require` method
params.require(:location).permit(:name, :notes, :longitude, :country, :latitude, :query, assets_attributes: [ :asset, :asset_content_type, :asset_file_name, :tempfile, :asset_file_size, :asset_updated_at, :_destroy])
end
Next, update the create action as below to ensure Locations are unique by name:
def create
#location = Location.find_by(name: location_params[:name])
unless #location
#location = Location.new(location_params)
end
respond_to do |format|
if #location.save
format.html { redirect_to #location, notice: ' <borat voice> Great success! </borat voice>' }
format.json { render :show, status: :created, location: #location }
else
format.html { render :new }
format.json { render json: #location.errors, status: :unprocessable_entity }
end
end
end

try using <%= a.file_field :asset, :multiple=>"true",:name=>"location[assets][asset][]"%> for handling multiple uploads.
Hope it helps

Related

How preview multiple images with nested form rails

I'm using paperclip to upload images and nested form.
I want to preview images as input, not just an image.
This is my form.
= nested_form_for #anime, html:{multipart:true} do |f|
- if #anime.errors.any?
#error_explanation
%h2= "#{pluralize(#anime.errors.count, "error")} prohibited this anime from being saved:"
%ul
- #anime.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :name
= f.text_area :name
.fields
=f.fields_for :images do |i|
=i.file_field :content
=i.link_to_remove "Remove"
.field
=f.link_to_add "add Image", :images
.actions
= f.submit 'Save'
This is my model.
class Image < ApplicationRecord
belongs_to :imageable, :polymorphic => true, optional:true
has_attached_file :content, :styles=>{:medium => "300x300>", :thumb => "100x100>"}
validates_attachment_content_type :content, :content_type => %w(image/jpeg image/jpg image/png)
end
class Anime < ApplicationRecord
has_many :images, :as => :imageable, dependent: :destroy
accepts_nested_attributes_for :images, :allow_destroy => true
end
This is my controller
class AnimesController < ApplicationController
before_action :set_anime, only: [:show, :edit, :update, :destroy]
# GET /animes
# GET /animes.json
def index
#animes = Anime.all
end
# GET /animes/1
# GET /animes/1.json
def show
end
# GET /animes/new
def new
#anime = Anime.new
#anime.images.build
end
# GET /animes/1/edit
def edit
end
# POST /animes
# POST /animes.json
def create
#anime = Anime.new(anime_params)
respond_to do |format|
if #anime.save
format.html { redirect_to #anime, notice: 'Anime was successfully created.' }
format.json { render :show, status: :created, location: #anime }
else
format.html { render :new }
format.json { render json: #anime.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /animes/1
# PATCH/PUT /animes/1.json
def update
respond_to do |format|
if #anime.update(anime_params)
format.html { redirect_to #anime, notice: 'Anime was successfully updated.' }
format.json { render :show, status: :ok, location: #anime }
else
format.html { render :edit }
format.json { render json: #anime.errors, status: :unprocessable_entity }
end
end
end
# DELETE /animes/1
# DELETE /animes/1.json
def destroy
#anime.destroy
respond_to do |format|
format.html { redirect_to animes_url, notice: 'Anime was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_anime
#anime = Anime.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def anime_params
params.require(:anime).permit(:name, images_attributes: [:content])
end
end
Please help me
Thanks so much.
ignore this message

500 error editing and updating multiple file uploads rails

I'm using Paperclip and I've added multiple file uploads to one of my models. Everything works fine except when I try to add new files to the existing ones already uploaded. It throws this error:
Unexpected error while processing request: expected Hash (got Array) for param `assets_attributes'
How can I fix this so that I can add new files? Thanks in advance.
asset.rb
class Asset < ActiveRecord::Base
belongs_to :member
belongs_to :listing
attr_accessible :asset
has_attached_file :asset, styles: { large: "700x700>", thumb: "100x100#" }
validates_attachment_size :asset, :less_than_or_equal_to=>10.megabyte
validates_attachment_content_type :asset, :content_type=>['image/jpeg', 'image/jpg', 'image/png', 'image/gif']
end
listing.rb
has_many :assets, :dependent => :destroy
accepts_nested_attributes_for :assets, :allow_destroy => true
attr_accessible :assets_attributes
listings/_edit_form.html.erb
<%= simple_form_for(#listing, :html => { class: 'form-horizontal ', :multipart => true }) do |f| %>
<% if #listing.errors.any? %>
<%= f.error_notification %>
<div>
<%= file_field_tag('listing_assets_asset', multiple: true, name: "listing[assets_attributes][][asset]", id: 'file-upload3', class: '') %>
</div>
<% end %>
listings_controller.rb
before_filter :authenticate_member!, only: [:new, :create, :edit, :update, :destroy]
before_filter :find_member
before_filter :find_listing, only: [:edit, :update, :destroy]
def new
#listing = Listing.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #listing }
end
end
# GET /listings/1/edit
def edit
end
# POST /listings
# POST /listings.json
def create
#listing = current_member.listings.new(params[:listing])
respond_to do |format|
if #listing.save
current_member.create_activity(#listing, 'created')
format.html { redirect_to #listing }
format.json { render json: #listing, status: :created, location: #listing }
else
format.html { render action: "new" }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
# PUT /listings/1
# PUT /listings/1.json
def update
respond_to do |format|
if #listing.update_attributes(params[:listing])
format.html { redirect_to #listing }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
private
def find_member
#member = Member.find_by_user_name(params[:user_name])
end
def find_listing
#listing = current_member.listings.find(params[:id])
end
The accepts_nested_attributes_for expects a hash for the *_attributes value that it processes, the hash it expects has the array indices as the keys, ie. it expects something like this:
asset_attributes: {
0 => { asset: value_for_0 },
1 => { asset: value_for_1 }
}
By creating the name of your form field as listing[assets_attributes][][asset] you're actually creating an array, ie.
asset_attributes: [
{ asset: value_for_0 },
{ asset: value_for_1 }
]
This is why you've received the error.
I think what you meant to name your field was: listing[assets_attributes][asset][] which would create:
asset_attributes: {
0 => { asset: [ array, of, IO, objects, for, your, files ] }
}
That fixed the error issue but did not fix my overall problem. I found the fix to my problem by looking at this article: http://www.railscook.com/recipes/multiple-files-upload-with-nested-resource-using-paperclip-in-rails/
I needed to change the way I was handling multiple uploads.
Changing my input to this:
<%= file_field_tag "assets[]", type: :file, multiple: true, id: 'file-upload3' %>
and adding the following to my create and update actions in my controler:
if params[:assets]
params[:assets].each { |asset|
#listing.assets.create(asset: asset)
}
end
Doing these things resolved my issue.

Why is adding multiple images to a gallery object not working at all

I am creating a gallery where you can upload multiple images via form.
The form is nested inside another form and when that is submitted it should create the gallery with the attached images inside it. When I check the output I get this which means its not submitting the correct images to the gallery object at all:
Parameters: {
"utf8"=>"✓",
"authenticity_token"=>"BJhkDx7rCRMIlXQ6T9FskXZe7+fdYxj0qm+VnCaC51w=",
"book"=>{
"jacket_cover" =>#<ActionDispatch::Http::UploadedFile:0x000001025d3128
#tempfile=#<File:/var/folders/mf/srx7jt8s2rdg0mn5hr98cvz80000gn/T/RackMultipart20140918-47766-1g9kyas>, #original_filename="559a7a477253d58f891f8e852162dfac.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"book[jacket_cover]\"; filename=\"559a7a477253d58f891f8e852162dfac.jpg\"\r\nContent-Type: image/jpeg\r\n">,
"title"=>"zd szw wrwr",
"synopsis"=>"<p>cfdcrgcgrere</p>\r\n",
"body"=>"<p>rccgregrrgerereg</p>\r\n",
"age"=>"19",
"publisher"=>"Dove books",
"author_attributes"=>{
"name"=>"zsdxfrrwg",
"biography"=>"<p>exffwfwefewewf</p>\r\n"},
"gallery_attributes"=>{
"images_attributes"=>{
"0"=>{
"file"=>[#<ActionDispatch::Http::UploadedFile:0x000001025d20e8 #tempfile=#<File:/var/folders/mf/srx7jt8s2rdg0mn5hr98cvz80000gn/T/RackMultipart20140918-47766-tk1rdb>, #original_filename="23ebb202a3655c6d0947251cce8625b6.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"book[gallery_attributes][images_attributes][0][file][]\"; filename=\"23ebb202a3655c6d0947251cce8625b6.jpg\"\r\nContent-Type: image/jpeg\r\n">, #<ActionDispatch::Http::UploadedFile:0x000001025d1ff8 #tempfile=#<File:/var/folders/mf/srx7jt8s2rdg0mn5hr98cvz80000gn/T/RackMultipart20140918-47766-j3ji7c>, #original_filename="559a7a477253d58f891f8e852162dfac.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"book[gallery_attributes][images_attributes][0][file][]\"; filename=\"559a7a477253d58f891f8e852162dfac.jpg\"\r\nContent-Type: image/jpeg\r\n">]
}
}
}
}, "commit"=>"Create Book"
}
The books_controller handles the submission of the gallery with the images in it:
class BooksController < ApplicationController
before_action :set_book, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!, only: [:new, :edit, :update, :destroy]
# GET /books
# GET /books.json
def index
#books = Book.order('created_at DESC').all
end
# GET /books/1
# GET /books/1.json
def show
# #book = Book.find(params[:id])
#book = Book.friendly.find(params[:id])
#gallery = #book.gallery
end
# GET /books/new
def new
#book = Book.new
#book.build_author
#gallery = #book.build_gallery
#gallery.images.build
end
# GET /books/1/edit
def edit
end
# POST /books
# POST /books.json
def create
#raise params.inspect
#book = Book.new(book_params)
#binding.pry
respond_to do |format|
if #book.save
format.html { redirect_to #book, notice: 'Book was successfully created.' }
format.json { render action: 'show', status: :created, location: #book }
else
format.html { render action: 'new' }
format.json { render json: #book.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /books/1
# PATCH/PUT /books/1.json
def update
respond_to do |format|
if #book.update(book_params)
format.html { redirect_to #book, notice: 'Book was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #book.errors, status: :unprocessable_entity }
end
end
end
# DELETE /books/1
# DELETE /books/1.json
def destroy
#book.destroy
respond_to do |format|
format.html { redirect_to books_url }
format.json { head :no_content }
end
end
# Get authors
# def reviews
# #book = Book.friendly.find(params[:id])
# #reviews = #movie.reviews
# respond_to do |format|
# format.html { render 'reviews/index' } # index.html.erb
# format.json { render json: #movies }
# end
# end
private
# Use callbacks to share common setup or constraints between actions.
def set_book
# #book = Book.find(params[:id])
#book = Book.friendly.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def book_params
params.require(:book).permit(:title, :synopsis, :body, :age, :publisher, :jacket_cover, author_attributes: [:name,:biography], gallery_attributes: [:name, :book_id ] )
end
end
book.rb
class Book < ActiveRecord::Base
has_attached_file :jacket_cover, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :jacket_cover, :content_type => /\Aimage\/.*\Z/
validates :jacket_cover, :title, :slug, :synopsis, :body, :age, :publisher, presence: true
validates_uniqueness_of :title
extend FriendlyId
friendly_id :title, use: [:slugged, :finders]
belongs_to :author
has_one :gallery
has_many :stories
accepts_nested_attributes_for :author
accepts_nested_attributes_for :gallery
scope :available, ->{ where(available: true) }
scope :unavailable, ->{ where(available: [nil, false]) }
end
image.rb
class Image < ActiveRecord::Base
belongs_to :gallery
has_attached_file :file, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :file, :content_type => /\Aimage\/.*\Z/
end
gallery.rb
class Gallery < ActiveRecord::Base
belongs_to :books
has_many :images
accepts_nested_attributes_for :books
accepts_nested_attributes_for :images, :allow_destroy => true
end
galleries_controller.rb
class GalleriesController < ApplicationController
before_action :set_gallery, only: [:show, :edit, :update, :destroy]
def index
#galleries = Gallery.all
end
def show
#gallery = Gallery.find(params[:id])
#images = #gallery.images
end
def new
#gallery = Gallery.new
##gallery.images.build
# #images = #gallery.build_images
# #gallery.images.build
end
def edit
#gallery.images.build
end
def create
#gallery = Gallery.new(gallery_params)
#image = Image.create()
##gallery.images.build
respond_to do |format|
if #gallery.save
format.html { redirect_to #gallery, notice: 'Gallery was successfully created.' }
format.json { render action: 'show', status: :created, location: #gallery }
else
format.html { render action: 'new' }
format.json { render json: #gallery.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #gallery.update(gallery_params)
format.html { redirect_to #gallery, notice: 'Gallery was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #gallery.errors, status: :unprocessable_entity }
end
end
end
def destroy
#gallery.destroy
respond_to do |format|
format.html { redirect_to galleries_url }
format.json { head :no_content }
end
end
private
def set_gallery
#gallery = Gallery.find(params[:id])
end
def gallery_params
params.require(:gallery).permit(:name, :book_id, :image)
#params.require(:gallery).permit(:name, :book_id, :images[], images_attributes: [:id, :file []])
#params.require(:gallery).permit(:name, :book_id, :images[images_attributes: [:file]])
# params.require(:gallery).permit(:name, :book_id, images_attributes: [:id, :image[:file]])
end
end
Added form in here that submits the gallery of images:
<%= simple_form_for(#book, :html => { :multipart => true } ) do |f| %>
<%= f.error_notification %>
<div class="inputs">
<div id="image" class="field">
<h3>Add the book image here</h3>
<div class="single-file">
<div class="file_upload">
<%= f.file_field :jacket_cover %>
</div>
</div>
</div>
<div id="title" class="field">
<h3>Add the title</h3>
<%= f.input :title %>
</div>
<div id="synopsis" class="field">
<h3>Add the book synopsis</h3>
<%= f.input :synopsis, :as => :ckeditor, :label => false, :input_html => { :ckeditor => { :toolbar => 'Full', :height => 400 } } %>
</div>
<div id="body" class="field">
<h3>Add the book body summary here</h3>
<%= f.input :body, :as => :ckeditor, :label => false, :input_html => { :ckeditor => { :toolbar => 'Full', :height => 400 } } %>
</div>
<div id="age" class="field">
<h3>Add the book age group</h3>
<%= f.input :age, collection: [['3-7', '3-7'],['7-11', '7-11'],['11-14', '11-14']], prompt: "Select age range" %>
</div>
<div id="publisher" class="field">
<h3>Who published the book</h3>
<%= f.input :publisher %>
</div>
<div id="school" class="field">
<h3>Schools reading this book (add the name and full address of the school)</h3>
<%= f.simple_fields_for :schools, :wrapper => 'inline' do |builder| %>
<%= render 'school_fields', :f => builder %>
<%= link_to_add_association 'add school', f, :schools, :render_options => {:wrapper => 'inline' }, :class => 'fa fa-plus' %>
<% end %>
</div>
</div>
<%#= f.select( :author_id, Author.all.map {|u| [u.name,u.id]}, {:include_blank => false, prompt: "No Author"} ) %>
<div id="author-inputs">
<h3>Add author</h3>
<%#= link_to 'New Author', new_author_path, :remote => true, :id => "new_author_link" %>
<%= f.simple_fields_for :author, :wrapper => 'inline' do |builder| %>
<%= render 'author_fields', :f => builder %>
<% end %>
</div>
<%= f.simple_fields_for :gallery do |builder| %>
<%= render 'galleries/form', :f => builder %>
<% end %>
<div class="actions">
<%= f.button :submit %>
</div>
<% end %>
When I check in the db console I cannot see any images inside the gallery when I search Gallery.all
I have created a gist file with all the necessary info in it.
Can anyone shed any light into this for me at all?
The main problem is with your parent form and model relationship.
In your book model you should have belongs_to :gallery instead of has_one :gallery. Also check your database. books Table should have gallery_id. As a database concept belongs_to should have parent table id. So model should be :
class Book < ActiveRecord::Base
has_attached_file :jacket_cover, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :jacket_cover, :content_type => /\Aimage\/.*\Z/
validates :jacket_cover, :title, :slug, :synopsis, :body, :age, :publisher, presence: true
validates_uniqueness_of :title
extend FriendlyId
friendly_id :title, use: [:slugged, :finders]
belongs_to :author
belongs_to :gallery
has_many :stories
accepts_nested_attributes_for :author
accepts_nested_attributes_for :gallery
scope :available, ->{ where(available: true) }
scope :unavailable, ->{ where(available: [nil, false]) }
end
and your gallery model should look like :
class Gallery < ActiveRecord::Base
has_many :books
has_many :images
accepts_nested_attributes_for :books
accepts_nested_attributes_for :images, :allow_destroy => true
end
Your parent model in form should be gallery model instead of book. And also make required changes in your gallery controller.

Rails 4 ForbiddenAttributesError - Nested Resource

I'm having "ForbiddenAttributesError" in my Rails 4 application. What am I missing here?
Also the problem is, why "examination_id" parameter isn't sent to the request?
Request
Started POST "/examinations/1/participations" for 127.0.0.1 at 2014-03-26 10:47:01 +0200
Processing by ParticipationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"EuGZIXKJE9a1It6Ema5t+g07vXngQoqPMV5qQBfekfg=", "participation"=>{"user_id"=>"1", "examination_id"=>"", "language_preference"=>"İngilizce", "exam_center_preference"=>"1", "disability"=>"0"}, "commit"=>"Sınava Başvur", "examination_id"=>"1"}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
Examination Load (0.2ms) SELECT "examinations".* FROM "examinations" WHERE "examinations"."id" = ? LIMIT 1 [["id", "1"]]
Completed 500 Internal Server Error in 5ms
ActiveModel::ForbiddenAttributesError (ActiveModel::ForbiddenAttributesError):
app/controllers/participations_controller.rb:37:in `create'
Routes.rb
resources :examinations do
resources :participations
end
Participation.rb
class Participation < ActiveRecord::Base
belongs_to :user
belongs_to :examination
end
Examination.rb
class Examination < ActiveRecord::Base
has_many :participations
has_many :users, :through => :participations
has_many :exam_fees, dependent: :destroy
has_many :exam_languages, dependent: :destroy
end
participations_controller.rb
#encoding: utf-8
class ParticipationsController < ApplicationController
before_filter :authenticate_user!
before_action :set_participation, only: [:show, :edit, :update, :destroy]
before_filter :get_examination
def get_examination
#examination = Examination.find(params[:examination_id])
end
# GET /participations
# GET /participations.json
def index
#participations = #examination.participations
end
# GET /participations/1
# GET /participations/1.json
def show
#participation = #examination.participations.find(params[:id])
end
# GET /participations/new
def new
#participation = Participation.new
end
# GET /participations/1/edit
def edit
end
# POST /participations
# POST /participations.json
def create
#participation = #examination.participations.new(params[:participation])
#participation.user = current_user
respond_to do |format|
if #participation.save
redirect_to #examination
format.html { redirect_to [#examination, #participation], notice: 'Sınav Katılımınız Oluşturuldu!' }
format.json { render action: 'show', status: :created, location: [#examination, #participation] }
else
render 'new'
format.html { render action: 'new' }
format.json { render json: #participation.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /participations/1
# PATCH/PUT /participations/1.json
def update
respond_to do |format|
if #participation.update(participation_params)
format.html { redirect_to [#examination, #participation], notice: 'Sınav Katılımını Güncellendi!' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #participation.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_participation
#participation = Participation.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def participation_params
params.require(:participation).permit(:user_id, :examination_id, :payment_status, :language_preference, :exam_center_preference, :disability)
end
end
/views/participations/_form.html.erb
<%= simple_form_for([#examination, #participation]) do |f| %>
<%= f.error_notification %>
<fieldset>
<legend>Sınav Katılımı</legend>
<%= f.input :user_id, :as => :hidden, :input_html => { :value => current_user.id } %>
<%= f.input :examination_id, as: :hidden %>
<%= f.input :language_preference, collection: ["Türkçe", "İngilizce", "Rusça"], label: 'Sınav Dili Tercihi' %>
<%= f.input :exam_center_preference, collection:ExamCenter.all, label_method: :city, as: :select, label: 'Sınav Merkezi Tercihi' %>
<%= f.input :disability, inline_label: 'Yardımcı İstiyorum', label: false %>
<%= f.button :submit, "Sınava Başvur" %>
</fieldset>
<% end %>
In order to assign parameters in Rails 4 to object, you should use strong parameters 'syntax' implemented in your participation_params method, instead of passing params directly. So change line:
#participation = #examination.participations.new(params[:participation])
to:
#participation = #examination.participations.new(participation_params)
Since you create your Participation record through association, you don't really need examination_id param in this controller. What's more, if you allow this parameter, it becomes easy to assign Participation to Examination other than from which context you create Participation, which I doubt to be desirable. So I guess you should remove examination_id both from fields in your form and from participation_params method.

button_to not passing correct id from params hash

The button_to is not passing the correct id to the line_item. In the log below you see the bike_id change from the correct '86' to the incorrect '1' (which coincidentally is my user_id). Any help would be appreciated. Below is the error from my development.log, then the code from my view and controllers. Thanks.
development.log
Started POST "/line_items?bike_id=86" for 127.0.0.1 at 2011-08-01 18:09:52 -0400
DEPRECATION WARNING: Setting filter_parameter_logging in ActionController is deprecated and has no longer effect, please set 'config.filter_parameters' in config/application.rb instead. (called from <class:ApplicationController> at /Users/willdennis/rails_projects/spinlister/app/controllers/application_controller.rb:8)
Processing by LineItemsController#create as HTML
Parameters: {"authenticity_token"=>"5GYQqvf7U5awhLrZ9Aw910ETf2kqOk3PI315jkjEfMU=", "bike_id"=>"86"}
[1m[35mCart Load (0.6ms)[0m SELECT "carts".* FROM "carts" WHERE ("carts"."id" = 8) LIMIT 1
[1m[36mBike Load (1.2ms)[0m [1mSELECT "bikes".* FROM "bikes" WHERE ("bikes"."id" = 86) ORDER BY bikes.created_at DESC LIMIT 1[0m
[1m[35mSQL (0.5ms)[0m INSERT INTO "line_items" ("bike_id", "cart_id", "created_at", "updated_at") VALUES (1, 8, '2011-08-01 22:09:53.208978', '2011-08-01 22:09:53.208978')
[1m[36mCart Load (1.5ms)[0m [1mSELECT "carts".* FROM "carts" WHERE ("carts"."id" = 8) LIMIT 1[0m
Redirected to http://localhost:3000/carts/8
Completed 302 Found in 251ms
line_items_controller.rb
def create
#cart = current_cart
#bike = Bike.find(params[:bike_id])
#line_item = #cart.line_items.build(:bike_id => #bike)
respond_to do |format|
if #line_item.save
format.html { redirect_to(#line_item.cart,
:notice => 'Line item was successfully created.') }
format.xml { render :xml => #line_item,
:status => :created, :location => #line_item }
else
format.html { render :action => "new" }
format.xml { render :xml => #line_item.errors,
:status => :unprocessable_entity }
end
end
end
views/bikes/show
<%= button_to "Rent this Bicycle!", line_items_path(:bike_id => #bike), {:id => "rentthisbike"} %>
bike.rb
class Bike < ActiveRecord::Base
belongs_to :user
has_many :line_items
attr_accessible :name, :description, :size, :biketype, :price, :photo, :id, :address, :city, :state, :zip, :latitude, :longitude, :neighborhood, :bike_id
end
line_item.rb
class LineItem < ActiveRecord::Base
belongs_to :bike
belongs_to :cart
accepts_nested_attributes_for :bike, :cart
attr_accessible :bike_id, :bike, :cart, :name, :description, :size, :biketype, :price, :photo, :id, :address, :city, :state, :zip, :latitude, :longitude, :neighborhood
end
cart.rb
class Cart < ActiveRecord::Base
has_many :line_items, :dependent => :destroy
belongs_to :user
accepts_nested_attributes_for :line_items
attr_accessible :bike_id, :line_items, :name, :description, :size, :biketype, :price, :photo, :id, :address, :city, :state, :zip, :latitude, :longitude, :neighborhood
end
Can you try this code and post the #### Line item attributes entry from your log file along with the params hash
I think this may be related to your current_cart method but I'm not sure
line_items_controller.rb
def create
#bike = Bike.find(params[:bike_id])
#line_item = current_cart.line_items.build
#line_item.bike = #bike
logger.debug("#### Line item attributes = #{#line_item.inspect}")
respond_to do |format|
if #line_item.save
format.html { redirect_to(#line_item.cart,
:notice => 'Line item was successfully created.') }
format.xml { render :xml => #line_item,
:status => :created, :location => #line_item }
else
format.html { render :action => "new" }
format.xml { render :xml => #line_item.errors,
:status => :unprocessable_entity }
end
end
end
Update.
Your previous code was fine except for this line
#line_item = #cart.line_items.build(:bike_id => #bike)
You were supplying the whole class as the value for the bike ID instead of the id of the bike. I know this is inconsistent with passing form parameters but that's just the way it is.

Resources