Item gets the collection_fields from his collections.
For each collection_field of the collection item may have a field_value
models
class Item < ActiveRecord::Base
belongs_to :collection
has_many :field_values, :dependent => :destroy
has_many :collection_fields, :through => :collection
accepts_nested_attributes_for :field_values, :allow_destroy => true
end
class Collection < ActiveRecord::Base
has_many :items, :dependent => :destroy
has_many :collection_fields, :dependent => :destroy
end
class CollectionField < ActiveRecord::Base
belongs_to :collection
belongs_to :field
has_many :items, :through => :collection
has_many :field_values, :dependent => :destroy
end
class Field < ActiveRecord::Base
has_many :collection_fields
end
class FieldValue < ActiveRecord::Base
belongs_to :item
belongs_to :collection_field
end
controller
def new
#item = Item.new
#item.collection = Collection.find(params[:collection])
#item.collection.collection_fields.each do |cf|
#item.collection_fields << cf
end
def edit
#item = Item.find(params[:id])
view
<%= form_for(#item, :html => { :multipart => true }) do |f| %>
<% #item.collection_fields.each do |cf| %>
<% f.label cf.field.name %>
<%= f.fields_for :field_values, cf.field_values.find_or_create_by_item_id(#item.id) do |fv| %>
<%= fv.text_field :valore %>
This code is working fine with the edit method, but when I try to add a new item I get:
Couldn't find FieldValue with ID=213 for Item with ID=
How should I implement these form fields correctly?
I've finally worked out a solution. It's not so elegant, but it works
- #collection.collection_fields.each do |cf|
= f.label cf.field.name
- if #item.new_record?
= f.fields_for :field_values, #item.field_values.build() do |field_value|
= field_value.text_field :valore
= field_value.hidden_field :collection_field_id, :value => cf.id
- else
= f.fields_for :field_values, #item.field_values.find_or_create_by_collection_field_id(cf.id) do |field_value|
%td= field_value.text_field :valore
Related
I have three objects: Contact, Sector, and Contact_sector.
Contact contains an id and some other irrelevant (non-reference) columns
Sector contains an id and sector column with ~10 editable entries
Contact_sector has a contact_id reference and a sector_id reference. In my mind I imagine that every sector that applies to some contact can be found here, and if a sector is un-applied it is removed from here.
I want to have a collection of checkboxes in the contact _form formed from list of entries in :sectors, but updating the form with certain boxes ticked adds/removes entries from :contact_sectors.
Where am I going wrong?
UPDATED: Fixed strong_params to permit sectors, now I am unable to find the sectors by id ActiveRecord::RecordNotFound (Couldn't find Sector with ID=["1", ""] for Contact with ID=1)
Models:
class Contact < ActiveRecord::Base
has_many :contact_sectors
has_many :sectors, through: :contact_sectors
accepts_nested_attributes_for :contact_sectors, :reject_if => :all_blank, :allow_destroy => true
accepts_nested_attributes_for :sectors, :reject_if => :all_blank, :allow_destroy => true
end
class Sector < ActiveRecord::Base
has_many :contact_sectors
has_many :contacts, through: :contact_sectors
def name_with_initial
"#{sector}"
end
end
class ContactSector < ActiveRecord::Base
belongs_to :contact
belongs_to :sector
end
View:
<%= f.fields_for(:sectors) do |s| %>
<%= s.collection_check_boxes :id, Sector.all,
:id, :name_with_initial,
{ prompt: true }, { class: 'form-control' } %>
<% end %>
Controller
def edit
#contact.sectors.build
end
def contact_params
#Not sure if I need something like this or not
params['contact']['sectors'] = params['contact']['sectors']['id'].split(',')
params.require(:contact).permit(:firstname, :lastname,
contact_sectors_attributes: [:id],
sectors_attributes: [:_destroy, {:id => []}])
end
Instead of creating the join model explicitly you can just declare the relationship as has_many through: and let ActiveRecord handle the join model:
class Contact < ActiveRecord::Base
has_many :contact_sectors
has_many :sectors, through: :contact_sectors
accepts_nested_attributes_for :sector,
reject_if: :all_blank, allow_destroy: true
end
class Sector < ActiveRecord::Base
has_many :contact_sectors
has_many :contacts, through: :contact_sectors
end
class ContactSector < ActiveRecord::Base
belongs_to :contact
belongs_to :sector
end
<%= form_for(#contact) do |f| %>
<%= f.fields_for(:sectors) do |s| %>
<%= s.collection_check_boxes :id, Sector.all,
:id, :name_with_initial,
{ prompt: true }, { class: 'form-control' } %>
<% end %>
<% end %>
models
class Contact < ActiveRecord::Base
has_many :sectors, through: :contact_sectors
has_many :contact_sectors
accepts_nested_attributes_for :sectors
end
class Sector < ActiveRecord::Base
has_many :contacts, :through => :contact_sectors
has_many :contact_sectors
end
class ContactSector < ActiveRecord::Base
belongs_to :contact
belongs_to :sector
end
view
<%= form_for(#contact) do |f| %>
<% Sector.all.each do |sector| %>
<%= check_box_tag "contact[sector_ids][]", sector.id, f.object.sectors.include?(sector) %>
<%= sector.sector %>
<% end %>
<% end %>
controller
def update
#To make sure it updates when no boxes are ticked
#contact.attributes = {'sector_ids' => []}.merge(params[:contact] || {})
end
def contact_params
params.require(:contact).permit(:firstname, :lastname, sector_ids: [])
end
Recommended reading:
http://millarian.com/rails/quick-tip-has_many-through-checkboxes/
Rails 4 Form: has_many through: checkboxes
I am trying to sort comments into events using a has_many :through association using checkboxes however the selected events are not saved. Here are my models:
class Comment < ActiveRecord::Base
has_many :categorizations
has_many :events, :through => :categorizations
end
class Event < ActiveRecord::Base
has_many :categorizations
has_many :comments, :through => :categorizations
end
class Categorization < ActiveRecord::Base
belongs_to :comment
belongs_to :event
end
My comments form looks like this:
<%= simple_form_for [#post, #comment] do |f| %>
<%= f.input :title %>
<%= f.association :events, :as => :check_boxes %>
<%= f.submit "Save" %>
After reading this answer, I added this to my event and comment controllers with no luck:
def comment_params
params.require(:comment).permit(:post_id, :title, :categorization_ids => [])
end
Try:
def comment_params
params.require(:comment).permit(:post_id, :title, :event_ids => [])
end
It's hard to know what's going on though without recreating it or seeing server logs, Hopefully this will solve it.
I am having a many to many association and totally confused on how to create checkboxes.
model: lodge.rb
has_many :lodge_facilities, :dependent => :destroy
has_many :facilities, through: :lodge_facilities, :dependent => :destroy
accepts_nested_attributes_for :facilities
model: lodge_facility.rb
belongs_to :lodge
belongs_to :facility
model: facility.rb
has_many :lodge_facilities, :dependent => :destroy
has_many :facilities, through: :lodge_facilities, :dependent => :destroy
in my form i tried
<%= form_for #lodge, :class =>'lodge_form', url: admins_lodge_path, method: :put,:html => {:multipart => true} do |f|%>
<%= f.fields_for :lodge_facilities do |fac| %>
<%= fac.check_box :ac %>
<%= fac.label :ac,'AC' %>
<%= fac.check_box :wifi %>
<%= fac.label :ac,'Wifi' %>
<% end %>
this displays checkbox but when i submit the form in my console i see Unpermitted parameters: lodge_facilities
In my controller i have added
def lodge_params
params.require(:lodge).permit(lodge_facilities_attributes:[:id,:lodge_id,:lodge_facility_id],facilities_attributes: [:id,:ac,:wifi,:internet,:bar,:restaurant,:gym,:pool,:laundry,:parking,:transportation] )
end
What am i missing?
Try this one:
def lodge_params
params.require(:lodge).permit(lodge_facilities_attributes:[:id,:lodge_id,:lodge_facility_id],lodge_facilities: [:id,:ac,:wifi,:internet,:bar,:restaurant,:gym,:pool,:laundry,:parking,:transportation] )
end
also you can use nested_form gem
https://github.com/ryanb/nested_form
I'm having issue creating a nested polymorphic form. I am following the solution from this problem:
Rails: has_many through with polymorphic association - will this work?
The description was: A Person can have many Events and each Event can have one polymorphic Eventable record
Here are the relevant models:
class Event < ActiveRecord::Base
belongs_to :person
belongs_to :eventable, :polymorphic => true
end
class Meal < ActiveRecord::Base
has_one :event, :as => eventable
end
class Workout < ActiveRecord::Base
has_one :event, :as => eventable
end
class Person < ActiveRecord::Base
has_many :events
has_many :meals, :through => :events, :source => :eventable,
:source_type => "Meal"
has_many :workouts, :through => :events, :source => :eventable,
:source_type => "Workout"
end
My controller looks like this:
def
#person = Person.new
#person.meals.new
#person.workouts.new
new
My view looks like this:
<%= form_for #person do |person| %>
<%= person.fields_for :meals, #person.meals.build do |meals| %>
<%= meals.text_field :food %>
<% end %>
<% end %>
The error I am currently getting is:
unknown attribute: person_id
I would think that the polymorphic association is hindering the creation of the object because meals can't be create until person has been created? Did I set up the form correctly? Thanks!
You'll need to include a person_id attribute in the events table (as per the belongs_to association)
There are also some other issues you should resolve:
Controller
def new
#person = Person.build
end
def create
#person = Person.new(person_attributes)
#person.save
end
private
def person_attributes
params.require(:person).permit(:your, :attributes, events_attributes: [:eventable_type, :eventable_id, meal_attributes: [:params], workout_attributes: [:params]])
end
Models
#app/models/person.rb
Class Person < ActiveRecord::Base
has_many :events
has_many :meals, :through => :events, :source => :eventable,
:source_type => "Meal"
has_many :workouts, :through => :events, :source => :eventable,
:source_type => "Workout"
def self.build
person = Person.new
person.events.build.build_meal
person.events.build.build_workout
end
end
Views
#app/views/people/new.html.erb
<%= form_for #person do |person| %>
<%= person.fields_for :events do |e| %>
<%= e.fields_for :meal %>
<%= e.text_field :food %>
<% end %>
<% end %>
<% end %>
I use paperclip to upload multi-file attached to studentcourseassignment,but i fail.
model
class StudentCourseAssignment < ActiveRecord::Base
attr_accessible :score, :comment, :finish_status,:attachments
accepts_nested_attributes_for :attachments
belongs_to :assignment
belongs_to :user
has_many :attachments ,:as => :attachmentable,:dependent => :destroy
end
class Attachment < ActiveRecord::Base
attr_accessible :user_upload
belongs_to :attachmentable , :polymorphic => true
has_attached_file :user_upload
end
controller
**new**
#sca = StudentCourseAssignment.new
#sca.attachments.build
#sca.attachments.build
**create**
#sca = StudentCourseAssignment.new(params[:student_course_assignment])
#assignment = Assignment.find(params[:assignment_id])
#sca.user = current_user
#sca.assignment = #assignment
if #sca.save
flash[:alert] = "success"
redirect_to course_years_path
else
flash[:alert] = "fail"
redirect_to course_years_path
end
** view**
<%= form_for #sca, :url => assignment_student_course_assignments_path(#assignment),
:html => { :id => 'student-assignment-form', :multipart => true } do |f| %>
file:
<%= f.fields_for :attachments do |a_f| %>
<%= a_f.file_field :user_upload %>
<%= submit_tag "create" %>
<% end%>
<% end %>
wrong
No association found for name `attachments'. Has it been defined yet?
if remove accepts_nested_attributes_for :attachments,it's still wrong
Attachment(#70201401779680) expected, got Array(#70201383294620)
hope your help!thx!
Change
from:
attr_accessible :score, :comment, :finish_status,:attachments
to:
attr_accessible :score, :comment, :finish_status,:attachments_attributes
I realize this is an old question, but fwiw I think you'll need to move
accepts_nested_attributes_for :attachments
to appear after
has_many :attachments, :as => :attachmentable,:dependent => :destroy
I hit this in a project once myself; pretty sure it boils down to accepts_nested_attributes_for expecting the relation to already be declared before its invoked.