Reputation: 163
I have three models:
class Item < ActiveRecord::Base
has_many :item_points
has_many :groups, through: :item_points
accepts_nested_attributes_for :item_points
end
class ItemPoint < ActiveRecord::Base
belongs_to :group
belongs_to :item
accepts_nested_attributes_for :group
end
class Group < ActiveRecord::Base
has_many :item_points
has_many :items, through: :item_points
end
The schema for items
create_table "items", force: :cascade do |t|
t.string "name", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
The schema for item_points
create_table "item_points", force: :cascade do |t|
t.decimal "points", null: false
t.integer "item_id", null: false
t.integer "group_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
The schema for groups
create_table "groups", force: :cascade do |t|
t.string "name", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
In my groups
table, I've created a number of rows, e.g. group 1 and group 2.
In the form for creating items
I'd really like to see a field each for group 1
and group 2
, so that I might be able to enter the points for that item. e.g. In item X, group 1 is worth 10 points, and group 2 is worth 5 points.
EDIT Added the form
The form:
<%= form_for(@item) do |item_form| %>
<div class="form-group">
<%= item_form.label :name %>
<%= item_form.text_field :name, :class => 'form-control' %>
</div>
<%= item_form.fields_for(:groups) do |groups_form| %>
<% group = groups_form.object_id.to_s%>
<%= groups_form.hidden_field :id %>
<%= groups_form.fields_for(:item_point) do |entity_form| %>
<%= entity_form.text_field :points %>
<% end %>
<% end %>
This provides me with a form, which contains one extra entry box, called item[groups][item_point][points]
, and has no label.
What I'd like to know is how do I get all of the rows I've added into groups as fields into a Rails Form? And when I do, how do I save the associated item_points data using strong parameters?
I've spent quite some time looking for an answer, and I can't seem to find anything other than a series of StackOverflow questions, which don't quite seem to have the same problem as me.
All help is wonderfully appreciated.
Upvotes: 0
Views: 74
Reputation: 1937
There's a helpful post with some examples at: https://robots.thoughtbot.com/accepts-nested-attributes-for-with-has-many-through. It specifically talks about adding inverse_of
on your associations.
In your view you'll need to use fields_for. You could (for example) put that in a table or a list and have each entry be a row.
If you share what you've tried in your view so far you may be able to get a more detailed response if you need it.
As for permitted_params
in your controller, you can nest them something like:
def permitted_params
params.permit(item: [
:name,
item_points_attributes: [
:id,
:points,
:group_id,
]
)
end
Update:
Rather than fields_for(:groups)
I think you want your controller to build the models for all the item_points (@item_points = Group.all.collect {|group| ItemPoint.new({group_id: group.id, item_id: @item.id}
).
Then you can use a fields_for(:item_points, @item_points)
.
You can add a label for the field so it's not just an unlabeled field using the HTML label tag.
Upvotes: 1