Facing a issue in select tag with accepts_nested_attributes_for with has many and explicit foreign key. I am not able to get the associated values listed.
Models
class PlantPlate < Plate
has_many :unit_plates, :foreign_key => 'parent_id', :dependent => :destroy
accepts_nested_attributes_for :unit_plates, :allow_destroy => true
end
class UnitPlate < Plate
belongs_to :plant_plate, :foreign_key => 'parent_id'
end
View
/plant_plates/_form.html.erb
<%= nested_form_for([ :admin, #plant_plate ]) do |f| %>
<%= f.fields_for :unit_plates do |unit_plate| %>
<%= unit_plate.collection_select :parent_id, UnitPlate.all,:id,:name %>
<%end
<%end%>
I want to list all the associated unit plates in select tag . But somehow now able to do that with this select tag.
Thanks in advance
Try out form_for instead:
<%= form_for([:admin, #plant_plate]) do |f| %>
<%= f.fields_for :unit_plate do |unit_plate| %>
<%= unit_plate.collection_select :parent_id, UnitPlate.all, :id, :name %>
<% end %>
<% end %>
Try out using basic f.select:
<%= f.select :parent_id, options_from_collection_for_select(UnitPlate.all, 'id', 'name') %>
Related
I have three models in my rails 5 application... What I want to do is to be able to create a note on the person's "show" view, then the note should automatically link to that person and any other person I choose to attach the note to.
Here's where I got up to
Note
class Note < ApplicationRecord
has_many :person_notes
has_many :people, through: :person_notes
accepts_nested_attributes_for :person_notes
end
Person Note (Join table)
class PersonNote < ApplicationRecord
belongs_to :person
belongs_to :note
end
Person
class Person < ApplicationRecord
has_many :person_notes
has_many :notes, through: :person_notes
accepts_nested_attributes_for :person_notes
accepts_nested_attributes_for :notes
end
In my "show" section of my "people" controller I have the following:
def show
#notep = Note.new()
#person.notes << #notep
end
This is creating a join of a new note to my person record every time I open the page (obviously i only want the join to happen on the note I have created.)
I have rendered this in a modal as a partial in my "show" view (there is an "end" and a submit button but it's in between 3 divs and I know they weren't the cause of the issue so i didn't include them.:
<%= simple_form_for(#notep, remote: true) do |f| %>
<%= f.error_notification %>
<%= f.input :subject %>
<%= f.input :note %>
<%= f.input :date, html5: true %>
<div class="input-field">
<%= f.check_box :isalert, :id => "alert" %>
<%= f.label :isalert, :for => "alert" %>
</div>
<div class="input-field">
<%= f.check_box :archived, :id => "archived" %>
<%= f.label :archived, :for => "archived" %>
</div>
<div class="input-field">
<%= f.check_box :deleted, :id => "deleted" %>
<%= f.label :deleted, :for => "deleted" %>
</div>
<%= f.input :datecreated, html5: true %>
<%= f.input :user_id %>
<%= f.simple_fields_for :person_notes do |builder| %>
<%= builder.association :person, label_method: :lstfstfullname %>
<%= builder.input :deleted %>
<%= builder.input :datecreated, html5: true %>
<%= builder.input :user_id %>
<% end %>
You can probably tell I'm a total newb, but I'd appreciate any help I can get.
Thanks,
Leah
If I'm understanding this correctly, you'll want a separate Notes controller and create action to handle note creation. Then in your People show view, you can add a form and input field that submits to NotesController#create.
How do you correctly fill in the following syntax to create a dropdown select tag with each option being the data of another table?
<%= form_for(#celebrity, :html => { :multipart => true }) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :image %>
<%= f.file_field :image %>
<%= f.label :character %>
<%= f.collection_select(:character, :celebrity_id, #characters, :id, :name) %> #this line is the question
<%= f.submit 'Save' %>
<% end %>
I followed the API documentation here, but it doesn't seem to work.
http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select
class Celebrity < ActiveRecord::Base
has_many :characters, through: :char_celeb_joins
has_many :char_celeb_joins
has_many :universes, through: :characters
end
class Character < ActiveRecord::Base
has_many :universes, through: :univ_char_joins
has_many :univ_char_joins
has_many :celebrities, through: :char_celeb_joins
has_many :char_celeb_joins
end
class Universe < ActiveRecord::Base
has_many :characters, through: :char_univ_joins
has_many :char_univ_joins
has_many :celebrities, through: :characters
end
But I get a
undefined method 'merge' for :name:Symbol
in the browser, when I go to a view that brings up this code.
NoMethodError in Celebrities#edit
The error is due to this line
<%= f.collection_select(:character, :celebrity_id, #characters, :id, :name) %>
When using with form_for,you have to set it like this
<%= f.collection_select(:celebrity_id, #characters, :id, :name) %>
And also your form_for object is #celebrity and you are giving :character as object to collection_select.It should be :celebrity in the collection_select too.Ofcourse you have worry about this when using collection_select without form_for.In your case it would be
<%= collection_select(:celebrity, :celebrity_id, #characters, :id, :name) %>
You can use helper:
Writer this code in any of the helper:
def character_for_select
Character.all.collect { |m| [m.id, m.name] }
end
Update your form
<%= form_for(#celebrity, :html => { :multipart => true }) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :image %>
<%= f.file_field :image %>
<%= f.label :character %>
<%= f.select(:character, character_for_select, :prompt => 'Select character') %>
<%= f.submit 'Save' %>
<% end %>
You will get your answer :)
Have you tried to use options_for_select. In your case, your code should be something like this:
app/helpers...
def options_for_characters( selected=nil )
options = Character.all.map { |c| [d.id, c.name] }
options_for_select( options, selected )
end
app/views...
...
<%= f.select(:character, options_for_characters, :prompt => 'Select character') %>
...
I have a product table and a related product table, related works one way:
Product(id: int, name: string)
RelatedProduct(id: int, product1: int, product2: int)
With the following models:
class Product < ActiveRecord::Base
validates :name, :uniqueness => true, :presence => true
has_many :relations, :class_name => "RelatedProducts", :foreign_key => :product1, inverse_of: :source
has_many :related_products, through: :relations, :source => :destination
end
class RelatedProducts < ActiveRecord::Base
belongs_to :source, :class_name => "Product", inverse_of: :relations
belongs_to :destination, :foreign_key => :product2, :class_name => "Product"
end
This works if I prepopulate the RelatedProducts table, the show view will correctly display all the related products. What I cannot figure out is how do to populate RelatedProducts from the html?
<%= form_for(#product) do |f| %>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="related-products field">
<h3>Related Products</h3>
<%= f.collection_check_boxes :related_products, Product.where.not(id: #product.id), :self, :name %>
</div>
<div class="actions">
<%= f.submit 'Update Products' %>
</div>
<% end %>
The strong parameters are defined as:
params.require(:product).permit(:name, related_products: [:id, :name])
My solution was to make the view use the ids and then submit them
<div class="related-products field">
<h3>Related Products</h3>
<%= f.collection_check_boxes :related_products, Product.where.not(id: #product.id), :id, :name %>
</div>
I then coupled this with a function in the model to convert the id list to a list of products
def related_products_list=(ids)
self.related_products = ids.reject(&:empty?).collect { |id| Product.find(id) }
end
This worked for submitting but the checkboxes would not be pre checked on edits. This was because the model talks about products but the view has a list of ids so would not spot matches. The solution I used was to manually loop through the collection to create the checkboxes instead of using collection_check_boxes.
<% Product.where.not(id: #product.id).each do |p| %>
<%= check_box_tag 'product[related_products][]', p.id, #product.is_related_to?(p), id: "product_related_products_" + p.id.to_s %>
<%= label_tag "product_related_products_" + p.id.to_s, p.name %>
<% end %>
I'm new to rails and just cant get that problem solved.
i have 3 models. Orders, Products and LineItems.
I want to have a order form with checkboxes for each product. User selects appropriate products and submits the order.
I cannot get the form to create the correct hash.
class Order < ActiveRecord::Base
attr_accessible :account_id, :user_id
has_many :line_items, :dependent => :destroy
end
class LineItem < ActiveRecord::Base
attr_accessible :account_id, :product_id, :order_id
belongs_to :orders
belongs_to :product
end
Here the view:
<%= form_for 'line_items[]' do |f| %>
<%= f.select :account_id, options_from_collection_for_select( Account.all,
:id, :name ), :prompt => 'Select Account' %>
<% Product.all.each do |product| %>
<div>
<%= check_box_tag 'line_items[product_ids][]', product.id %>
</div>
<% end -%>
<div>
<%= f.submit 'save' %>
</div>
thanks!
You would need to use accepts_nested_attributes_for in your model to enable nested atributes from associated models. You may also want to check out this railscast and adapt to your needs.
For example in the orders model:
class Order < ActiveRecord::Base
attr_accessible :account_id, :user_id
has_many :products #This makes the association to products
has_many :line_items, :dependent => :destroy
accepts_nested_attributes_for :products #This allows the attributes from products accessible
end
Then the form could be:
<%= form_for #order do |f| %>
<%= f.select :account_id, options_from_collection_for_select( Account.all,
:id, :name ), :prompt => 'Select Account' %>
<%= f.fields_for :product do |product_form| %>
<%= product_form.check_box :id %>
<% end %>
<%= f.submit %>
<% end %>
I have a form that creates a signed_user. This is the first line of the form:
<%= form_for(setup_user(#signed_user)) do |f| %>
The setup_user is in my application helper:
def setup_user(user)
user.tap do |u|
u.build_invitation
end
end
These are the model associations:
signed_user model:
has_one :invitation, :foreign_key => "sender_id"
invitation model:
belongs_to :sender, :class_name => 'SignedUser'
So why is a user being created without an invitation? I checked my console and the user's invitation is nil...
What you want is a nested form. All the details are available in the article but basically make sure you use accepts_nested_attributes_for in your SignedUser model.
class SignedUser < ActiveRecord::Base
...
has_one :invitation, :foreign_key => "sender_id"
accepts_nested_attributes_for :invitation, :allow_destroy => true
...
end
If you want your form to modify attributes from the Invitation model (in addition to attributes from the SignedUser), you'll also need to use fields_for in your form. For example:
<%= form_for setup_user(#signed_user) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
// More user form fields
<%= f.fields_for :invitation do |cf| %>
<%= cf.label :event_name %>
<%= cf.text_field :event_name %>
// More invitation form fields
<% end %>
<%= submit_tag %>
<% end %>