rails 4 unpermitted params nested form - ruby-on-rails

I know there are alot of these kinds of posts on SO, and I think Ive read and tried each of them, all without success.
I have Post and Image models that I need to work together with a many to one relationship.
class Post < ActiveRecord::Base
has_many :images
end
class Image < ActiveRecord::Base
belongs_to :post
mount_uploader :file, images_uploader
end
Here is the post_parms declaration in my posts controller, which includes all of the fields in my image model migration.
private
def post_params
params.require(:post).permit(:title, :content, image_attributes: [:id, :post_id, :file])
end
and here is my post creation form where, I hope to allow multiple image asset creation with each post.
<%= form_for #post, html: {class: "pure-form pure-form-stacked"} do |post| %>
<%= post.fields_for :image, :html => { :multipart => true } do |image| %>
<%= image.label :file, "Upload Image:" %>
<%= image.file_field :file, multiple: true %>
<% end %>
<fieldset class="post-form">
<%= post.label :title %>
<%= post.text_field :title %>
<%= post.label :content %>
<%= post.text_area :content, :class => "redactor", :rows => 40, :cols => 120 %>
</fieldset>
<div class = "button-box">
<%= post.submit class: "pure-button pure-button-primary" %>
<%= link_to "Cancel", posts_path, :class => "pure-button" %>
</div>
Despite repeated effort and reading every post I can find on this topic, I'm still getting:
Unpermitted parameters: image
The trouble here is that this error provides no clue where to start looking for the problem. Since Im not really sure where to look next I thought I would post it here looking for more professional opinions.

Update the Post model as below:
class Post < ActiveRecord::Base
has_many :images
accepts_nested_attributes_for :images ## Add this
end
This way upon form submission you would receive the image attributes in key images_attributes and not image which you are currently receiving which is causing the warning as Unpermitted parameters: image
As you have 1-M relationship between Post and Image
You need to update post_params as below:
def post_params
params.require(:post).permit(:title, :content, images_attributes: [:id, :post_id, :file])
end
Use images_attributes (Notice plural images) and NOT image_attributes (Notice singular image)
And change fields_for in your view as
<%= post.fields_for :images, :html => { :multipart => true } do |image| %>
Use images (Notice plural) and NOT image (Notice singular)
UPDATE
To resolve uninitialized constant Post::Image error
Update Image model as below:
class Image < ActiveRecord::Base
belongs_to :post
## Updated mount_uploader
mount_uploader :file, ImagesUploader, :mount_on => :file
end
Also, suggested to remove multiple: :true from
<%= ff.file_field :file, multiple: true %>

Related

rails file_field not showing

I would like to make my app upload multiple files with Shrine, but one doc suggests two file_fields whereas the other suggests only one. After posting a question to their discourse forum, it was suggested that I hide the one named files[]. Whether I do this or not, the first file_field always fails to render. Why does this field not display?
<%= form_for #item, html: { enctype: "multipart/form-data" } do |f| %>
<%= f.fields_for :photos do |i| %>
<%= i.label :image %>
<%= i.hidden_field :image, value: i.object.cached_photos_data, class: "upload-data" %>
<%= i.file_field :image, class: "upload-file" %> /// why is this not rendering?😢
<% end %>
<%= file_field_tag "files[]", multiple: true %> // what purpose does this one serve?
<%= f.text_field :title %>
<%= f.submit "Submit" %>
<% end %>
Models:
class Item < ApplicationRecord
has_many :photos, as: :imageable, dependent: :destroy
end
class Photo < ApplicationRecord
include ImagesUploader::Attachment(:image)
belongs_to :imageable, polymorphic: true
validates_presence_of :image
end
Controller:
class ItemsController < ApplicationController
def new
#item = current_user.items.new
end
def create
#item = current_user.items.create(item_params)
#item.save
end
private
def item_params
params.require(:item).permit(:title, photos_attributes: { image: [] })
end
end
Read the first link carefully: It says that the single field (i.file_field :image) is used to display existing images (which is why it's wrapped in f.fields_for :photos in the example) and the multiple field (file_field_tag "files[]", multiple: true) is used to upload new files. So if your #item doesn't have an :image, then the field isn't shown.
Let me know if this needs any further clarification – happy to help!

Rails Paperclip Error: No handler found for

This is quite a common error and I have went through many answers but nothing worked for me. Can you please help, where I am going wrong?
Scenario: I have an item and image table and when user adds an item, he/she must add at least one image. When I save the form after attaching an image it gives an error. The code snippets and error screenshot are attached below:
item.rb
class Item < ApplicationRecord
belongs_to :user, class_name: 'User', foreign_key: :user_id
has_many :images, class_name: 'Image', foreign_key: :item_id, dependent: :destroy
accepts_nested_attributes_for :images, allow_destroy: true
end
image.rb
class Image < ApplicationRecord
belongs_to :item, foreign_key: :item_id, optional: true
has_attached_file :image, styles: { small: '64x64', med: '100x100', large: '200x200' },
default_url: '/images/:id/:filename'
validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/
end
items_controller.rb
class ItemsController < ApplicationController
def new
#item = Item.new
#item.images.build
#new.html.erb
end
def create
#item = Item.new(item_params.merge(user_id: current_user.id))
if #item.save
redirect_to items_path
else
render :new
end
end
private
def item_params
params.require(:item).permit(:name, :category, :qty, :cost, :description,
:city, :postal_code, :country,
images_attributes: [:id, :item_id, :_destroy, image: []])
end
end
new.html.erb
<div class="container">
<h2> <% if current_user.items.blank? %> Become a seller! <% end %> Add a new item </h2> <br>
<%= form_for #item, url: {action: :create}, html: { multipart: true } do |f| %>
<%= item_error_messages! %>
<div class="form-group">
<%= f.label :name, class:'control-label col-sm-2' %>
<div class="col-sm-10">
<%= f.text_field :name, class: 'form-control', placeholder: 'Enter name' %>
</div>
</div>
<%= f.fields_for :images, #item.images.build do |img| %>
<%= img.file_field :image, multiple: true %>
<% end%>
<br><br>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10" style="margin-bottom: 40px;">
<%= f.submit 'Save', class:'btn btn-default' %>
</div>
</div>
<% end %>
</div>
Error:
What could be the possible issue? Most of the solutions I've read suggest adding multipart: true in form tag but it is already there.
Thanks
I think you problem is related with the fact that you are trying to save more than one attached file per model. Apparently, Paperclip don't treat this case very well, so you need to do it by your own hand.
If you want to save multiples files at the same time, you can follow the accept answer in the link below that example how to achieve that:
Just a resume from the link below:
1 - To save multiple files in the above example you, do not need add
multiple: true option, it will cause an error when saving.
2 - About params: This will cause an error because the model does not know what to do with an array of images
3 - To save more than one file at the same time, you need to use your own
handler
Rails 4 multiple file attachments with Paperclip
Good luck!
#UPDATE
Ideas about to how save multiples file at once:
1 - You will need to have a form with a dynamically input for files.
So each input can get the entry for each file. You can achieve that
writing your own .js lib or using a gem like "Cocoon". You will be
using nested attributes here.
2 - The strong parameter in your controller will be accepting you Item
model and an array of files.
3 - You will have to edit your method to save your data. E.g (in your
case #item.save won't work because paperclips it's not design to
accept an array of files). So, in your Item model you will have to
write a method similar to the below:
(pseudo-code)
def save(item_attributes, array_of_files)
#item = Item.new( -- add here only Item attributes --)
#item.save
# Here you are creating a model file for each file you are saving.
# So there will be N file model for 1 item.
for file in array_of_files
#file = File.new( #item.id, file)
#file.save
end
# here you can implement transaction in case a error occurs.
# and shows the error to your client through Item model
# google how to do this (transaction and Active Record class).
end

Nesting Carrierwave images in Rails 4

This is actually a two part question
For the record - I am using Simple_form, Carrierwave and awesome_nested_fields gems.
In my app I have events, each event has a speaker, and each speaker has a picture. Pictures are not a separate table, they're stored under 'speakers'
event.rb
class Event < ActiveRecord::Base
belongs_to :type
...
has_many :speakers
accepts_nested_attributes_for :speakers, allow_destroy: true
...
speaker.rb
class Speaker < ActiveRecord::Base
belongs_to :event
mount_uploader :photo, PhotoUploader
end
strong parameters (events controller):
private
def event_params
params.require(:event).permit(:title, :description, :type_id, :price, :program,
:start_date, :end_date, :image, category_ids: [],
speakers_attributes: [ :id, :name, :photo, :status, :description, :url, '_destroy'])
end
The photos are uploaded and replaced no problem, however when it comes to editing, troubles begin:
edit form:
<%= simple_form_for #event, html: {multipart: true} do |f| %>
<%= f.other_stuff %>
<%= f.nested_fields_for :speakers do |f| %>
#Problem 1 - deleting uploaded images
<%= f.check_box :remove_avatar %> # DOES NOT WORK
<%= f.check_box :_destroy %> # DOES NOT WORK
Problem 2 - showing an uploaded image
<%= image_tag(#event.speaker.photo_url) if #event.speaker.photo? %> # Error - undefined method `photo?'
<% end %>
<% end %>
I am pretty sure the first problem is connected to strong parameters, and I have tried many variations, but so far I couldn't figure out the correct ones (:photo_remove, [photos_attributes['_destroy']], etc).
The second problem with displaying uploaded images can be solved by inserting
<%= image_tag #event.speakers[0].photo %>
in my code, however if there are several speakers, I need to change the array integer, and I cant seem to figure out how to do that (tried writing a helper method, but nothing good so far).
Any help would be appreciated, thank you

rails 3.2.x, simple_form_for, paperclip, multiple uploads

Ok just to get this out of the way I dont need anything fancy just to be able to list 5 file fields for uploading images. Currently, I receive no errors when visiting the form but the form file upload inputs aren't being display where the rest of the form is rendering properly.
Things I have working so far:
s3 with paperclip
Upload single files
With that said Ill post portions of the models to give a better picture of my setup:
My product model:
has_many :photos
attr_accessible :name, :description, :price, :category_id, :location_ids
accepts_nested_attributes_for :photos, :allow_destroy => true
My photo model:
belongs_to :products
attr_accessible :image,
has_attached_file :image, styles: {
thumb: '100x100>',
square: '200x200#',
medium: '300x300>'
}
My product controller:
def new
#product = Product.new
5.times { #product.photos.build }
end
My product post form:
<%= simple_form_for #product,
:url => admin_products_path do |form| %>
<% form.simple_fields_for :photos do |builder| %>
<% if builder.object.new_record? %>
<p>
<%= builder.input :image %>
</p>
<% end %>
<% end %>
....
<% end %>
I tried to keep this as simple as possible since this is my first implementation. Most of the documentation online was for a little bit older rails but I attempted to make it work with rails 3.2.1, paperclip, simple_forms_for, aws-sdk.
Please help :D
I believe you need to use the erb output syntax for the simple_fields_for nested attributes helper:
<%= form.simple_fields_for :photos do |builder| %>
# ^ ...

carrierwave + nested models: file_field not calling "create" method

I am trying to follow Railscast Ep 381 to integrate multi-file upload into my Rails app. For my app, the Projects model has many Steps, and Steps have many Images. The Image model is using a Carrierwave uploader.
Right now, I'm able to upload single image files from within the edit_steps path. But I'm trying to design the upload interface so that a gallery on the edit_steps page automatically refreshes once new images have been added (so once images have been selected but the form has not yet been submitted).
According to the Railscast episode, when you select images, they should automatically call the create action for each file. But my application is clearly not doing that. How can I ensure that the create method of the Image model is being called?
step.rb
class Step < ActiveRecord::Base
extend FriendlyId
friendly_id :number
attr_accessible :description, :name, :number, :project_id, :images_attributes
belongs_to :project
has_many :images
accepts_nested_attributes_for :images, :allow_destroy => :true
end
image.rb
class Image < ActiveRecord::Base
attr_accessible :project_id, :step_id, :file, :caption
belongs_to :step
belongs_to :project
mount_uploader :file, FileUploader
end
views/steps/edit.html.erb
%= semantic_form_for [#project, #step], :html => {:multipart => true} do |f| %>
<%= f.inputs do%>
....
<div id="images">
<%= render :partial => 'images/image', :collection => #step.images.all %>
</div>
<div class="clear"></div>
....
<%= f.fields_for :images, Image.new do |image_form| %>
<%= image_form.file_field :file, multiple: true, name: "image[file]"%>
<%end%>
javascript/images.js.coffee
jQuery ->
$('#new_image').fileupload
dataType: "script"
controllers/images.controller
def create
#image = Image.create(params[:image])
end
images/create.js.erb
<% if #image.new_record? %>
alert("Failed to upload image: <%= j #image.errors.full_messages.join(', ').html_safe %>");
<% else %>
alert("adding images")
$("#images").append("<%= j render(#image) %>");
<% end %>

Resources