Eric
Eric

Reputation: 380

Rails: How do I iterate through nested attributes in model when creating new entries

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

Answers (1)

Arvoreniad
Arvoreniad

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

Related Questions