Reputation: 380
I have researched how to do this and the best resource I have found is at http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
Specifically on that page, it says:
member = Member.create(params[:member])
member.posts.length # => 2
member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!'
member.posts.second.title # => 'The egalitarian assumption of the modern citizen'
I am trying to iterate through my nested attributes and create a new Entry object for each Scene that is nested inside the Incident Model, but how do you iterate through using .first and .second ... and so on.
So the over all goal here is to have a complex form where when you create an incident, you can create many scenes within that incident using nested attributes. When you create or update a scene or incident, it needs to fire off and create a new log entry that is tied to the incident's ID. Beyond that, I also need to fire off a callback for when they assign an asset to a scene and assign a scene_role to the asset.
I have not been able to figure out, through hours of research, how to iterate through the nested attributes other than using .first and .second.
Here is my Incident model:
class Incident < ActiveRecord::Base
has_many :scenes
has_many :scene_assignments
has_many :entries
after_create :create_action
after_update :update_action
accepts_nested_attributes_for :scenes
accepts_nested_attributes_for :scene_assignments
def create_action
@entry = Entry.new(incident_id: self.id, name: "Created Incident - #{self.name}")
@entry.save
self.scenes.each do
@scene_entry = Entry.new(incident_id: self.id, name: "#{self.scenes.first.name} was created")
@scene_entry.save
end
end
def update_action
@entry = Entry.new(incident_id: self.id, name: "Updated Incident - #{self.name}")
@entry.save
end
end
How it works currently is: It will create the log entry for the incident with the incident's name. I also filled in 2 scenes in the form. So it will create 2 entries for those scenes in the entries table with the incident ID properly tying the entries to the incident. However, it will only print the name for the first scene in the log entry.
Also, I know it is counter intuitive to call the column name: for the log entry, but that is where it is storing the entry, in that field.
So the database table looks like
ID | NAME | INCIDENT_ID and the records look like:
1 | Incident Name | 50
2 | Scene 1 Name | 50
3 | Scene 1 Name | 50
Upvotes: 1
Views: 1795
Reputation: 510
If you want to iterate over the nested attributes of a model just use a normal Ruby loop:
member.posts.each do |post|
...
end
You can do whatever you like with the post
variable within the loop - update, save, destroy etc.
Upvotes: 1