I have the following form declaration for a new kindergarten
<%= form_for #kindergarten, :html => {:multipart => true} do |f|%>
<%= render 'shared/error_messages', object: f.object %>
</br>
<%= f.fields_for :photos do |p| %>
<%= p.label 'upload photo'%>
<%= p.file_field :image %>
<% end %>
</br>
<%= render 'about_company', f: f%>
</br>
<%= render 'contact', f: f %>
<%= f.submit "Create my account", class: "btn btn-large btn-primary" %>
<%end%>
The logic behind this is that 1 kindergarten can have multiple photos.
Here are the model declarations:
Kindergarten
has_many :photos, limit: 7, dependent: :destroy
accepts_nested_attributes_for :photos
Photo
attr_accessible :image, :logo, :kindergarten_id
belongs_to :kindergarten
mount_uploader :image, ImageUploader
validates :kindergarten_id, presence: true
validates :image, presence: true
And here's how the kindergartens controller looks like:
def new
#kindergarten = Kindergarten.new
#kindergarden.photos.build
end
Now, when #kindergarten new is generated i get the following error:
undefined method 'photos' for nil:NilClass
Application Trace | Framework Trace | Full Trace
app/controllers/kindergartens_controller.rb:5:in `new'
You've written #kindergarden.photos.build instead of #kindergarten.photos.build. I hope the typo is not in the actual code.
Also try #kindergarten=Kindergarten.create . If you are calling new just creates an unsaved record, which should be followed by a call to the save method. That could be the reason for the NilClass error.
Related
I'm using Dragonfly to upload images to model Photo which is associeted to others models. For example:
MODEL: Post
class Post < ActiveRecord::Base
has_many :photos, dependent: :destroy
accepts_nested_attributes_for :photos, allow_destroy: true,
reject_if: lambda {|attributes| attributes['image'].blank?}
MODEL Photo
class Photo < ActiveRecord::Base
extend Dragonfly::Model::Validations
dragonfly_accessor :image
dragonfly_accessor :image do
after_assign { |img| img.encode!('jpg', '-quality 80') }
end
It works fine, even when I change the input to upload multiple files at the same time
FORM VIEW:
works:
<%= f.fields_for :photos do |photo| %>
<%= photo.file_field :image, class: "form-control" %>
<% end%>
doesn't works:
<%= f.fields_for :photos do |photo| %>
<%= photo.file_field :image, class: "form-control", multiple: true, name: 'photo[image]' %>
<% end%>
How can I upload multiple files at the same time to associeted model?
Thanks!
UPDATE:
I tried:
controller. Create action
#post = Post.new(seminovo_params)
params[:photos]['image'].each do |a|
#photo = #post.photos.create!(:image => a)
end
View
<%= f.fields_for :photos, #post.photos.new do |photo| %>
<%= photo.file_field :image, :multiple => true, name: "photos[image][]" %>
Yo need to define params and get those params this way
Your new method should contain
def new
# Your new form object
#photo = #post.photos.build
end
In controller method use this
params[:photos]['avatar'].each do |a|
#photo = #post.photos.create!(:image => a)
end
Your form should look like,
<%= form_for(#post, :html => { :multipart => true }) do |f| %>
<%= f.fields_for :photos do |p| %>
<div class="field">
<%= p.label :image %><br>
<%= p.file_field :image, :multiple => true, name: "photos[image][]" %>
</div>
<% end %>
Hi all. When I open /courses/new (or /courses/some_id/edit), browser returns this error:
Showing /app/views/dashboard/courses/_price.html.erb where line #1 raised:
undefined method `label' for nil:NilClass
Here are codes, _form.html.erb:
<%= simple_form_for [:dashboard, #course], html: { multipart: true } do |f| %>
//////
<%= f.fields_for :prices do |p|%>
<%= render 'price', :f => 'prices' %>
<% end %>
<%= link_to_add_association 'Add', f, :prices %>
////////
_price.html.erb:
<%= p.label :price %>
<%= p.text_field :price %>
<%= p.label :desc %>
<%= p.text_field :description %>
<%= link_to_remove_association "remove", f %>
Models:
class Price < ActiveRecord::Base
belongs_to :course
end
class Course < ActiveRecord::Base
has_many :prices
accepts_nested_attributes_for :prices, :reject_if => :all_blank, :allow_destroy => true
end
How resolve this error? And why it has arisen?
You are using simple_form_for,so i guess this line
<%= f.fields_for :prices do |p|%>
should be
<%= f.simple_fields_for :prices do |p|%>
Have a look at the Git for more Info.
In your _price.html.erb partial view, your are using a form builder that does not exists (is nil) because you did not pass it as argument:
# _price.html.erb
<%= p.label :price %>
#^ the variable `p` is the form builder here
To solve this problem, you have to pass the form builder to the partial view, like this:
<%= f.fields_for :prices do |p| %>
<%= render 'price', :f => 'prices', p: p %>
#^^^^ We pass the variable `p` (form builder) to the partial
<% end %>
Hope this helps!
I have a little problem with gem nested_form. I have:
class Factura < ActiveRecord::Base
attr_accessible :itemfacturas_attributes
has_many :itemfacturas
has_many :productos, :through => :itemfacturas
accepts_nested_attributes_for :itemfacturas, :reject_if => lambda { |a| a[:descripcion].blank? }, :allow_destroy => true
and the ItemFactura class
class Itemfactura < ActiveRecord::Base
attr_accessor :vu, :vt, :descripcion
belongs_to :factura
belongs_to :producto
I used the gem in the facturas/new view to add itemfacturas.
<%= f.fields_for :itemfacturas do |b| %>
<%= render 'itemfacturas/itemfacturas', f: b %>
<% end -%>
<%= f.link_to_add "Agregar item", :itemfacturas %>
And the partial is:
<%= f.number_field :cantidad, :min => 0, :value => 1 %>
<%= f.text_field :descripcion, :class => "desc_autocomplete" %>
<%= f.text_field :vu %>
<%= f.text_field :vt %>
<%= f.hidden_field :producto_id%>
<%= f.link_to_remove "Eliminar" %>
But I have this error:
NoMethodError in Facturas#new
Showing
/Users/fabricioflores/desarrollo/facturacion/app/views/itemfacturas/_itemfacturas.html.erb
where line #7 raised:
undefined method `link_to_remove' for
If I comment line that contains link_to_remove I have another error about link_to_add
I followed steps from https://github.com/ryanb/nested_form but it did't work. I'm using Rails 3.2.9 and nested_form (0.3.1)
Ok I solved it. In the form of facturas/new I need to put
<%= nested_form_for #factura do |f| %>
This was the reason that can't find the link_to_add and link_to_remove, because is a different helper.
I have an error "Can't mass-assign protected attributes: Upload", but I have assigned it to be accessible.
This is a nested form with a polymorphic association.
Models
class Upload < ActiveRecord::Base
attr_accessible :link, :post_id
belongs_to :uploadable, polymorphic: true
end
class Post < ActiveRecord::Base
attr_accessible :description, :title, :uploads_attributes
has_many :uploads, as: :uploadable
accepts_nested_attributes_for :uploads, :reject_if => lambda { |a| a[:content].blank?
}, :allow_destroy => true
end
I tried too put accept_nested ... for :uploadable but tells me dont exist the association
The action new on the controller is this one
def new
#post = Post.new
#post.uploads.new
end
and here is the form for create
<%= form_for [:admin,#post], remote: true, :html => {:multipart => true} do |f| %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title%>
</div>
<div class="field">
<%= f.label :description%><br />
<%= f.text_area :description %>
</div>
<div>
<%= f.fields_for :upload do |builder| %>
<%= render 'upload_fields', f: builder %>
<% end %>
<%= link_to_add_fields "Add Upload", f, :uploads %>
</div>
<div class="actions">
<%= f.submit%>
</div>
<% end %>
The partial ...
<fieldset>
<%= f.label :file %><br />
<%= f.file_field :file %>
<%= f.hidden_field :_destroy %>
<%= link_to "remove", '#', class: "remove_fields" %>
</fieldset>
Dont think the javascript affects, so Im not going to put it here.
How I cna solve "Can't mass-assign protected attributes" on polymorphic asociations ?
Plz need help on this anyone. Cant belive I cant upload files, looks so simple on tutorials, and Its not working, or I get a Can't mass assign orthe upload its not saved ....
Try to use #post.uploads.build instead of #post.uploads.new
The associated model needs to know the identity of her parent to save the relationship.
I recommend you the following railscast: Polymorphic Association.
#uploads_controller.rb
before_filter :load_uploadable
def create
#upload = #uploadable.uploads.new(params[:upload])
....
end
private
def load_uploadable
resource, id = request.path.split('/')[1, 2] # /posts/1
#uploadable = resource.singularize.classify.constantize.find(id)
end
This line inside your view:
<%= f.fields_for :upload do |builder| %>
Should be this:
<%= f.fields_for :uploadable do |builder| %>
Because the association on the Post model is called "uploadable", not "upload".
For nested attributes to work, you will need to specify the model does accept nested attributes for this model, which can be done by putting this line underneath the belongs_to in your model:
accepts_nested_attributes_for :uploadable
And then you will need to make these attributes accessible, which you can do with this:
attr_accessible :uploadable_attributes
I have the following form declaration for a new kindergarten
<%= form_for #kindergarten, :html => {:multipart => true} do |f|%>
<%= render 'shared/error_messages', object: f.object %>
</br>
<%= f.fields_for :photos do |p| %>
<%= p.label 'upload photo'%>
<%= p.file_field :image %>
<% end %>
</br>
<%= render 'about_company', f: f%>
</br>
<%= render 'contact', f: f %>
<%= f.submit "Create my account", class: "btn btn-large btn-primary" %>
<%end%>
The logic behind this is that 1 kindergarten can have multiple photos.
Here are the model declarations:
Kindergarten
has_many :photos, limit: 7, dependent: :destroy
accepts_nested_attributes_for :photos
Photo
attr_accessible :image, :logo, :kindergarten_id
belongs_to :kindergarten
mount_uploader :image, ImageUploader
validates :kindergarten_id, presence: true
validates :photo, presence: true
I am struggling with this for a few hours now, and I can't understand why the "upload file" button and label are not showing up. When i say now showing up, i mean they are completely ignored and not present in the rendered html.
Before rendering the form for a new # kindergarden, you'll need to build a photo association for this to work:
def new
#kindergarden = Kindergarden.new
#kindergarden.photos.build # provides a photo object to use in the form
# rest of your action
end
Also, if you wanted multiple photo fields in the form, you could do something like:
5.times { #kindergarden.photos.build }