6

Say you have this structure:

class House < ActiveRecord::Base
  has_many :rooms
  accepts_nested_attributes_for :rooms
  attr_accessible :rooms_attributes
end

class Room < ActiveRecord::Base 
  has_one :tv
  accepts_nested_attributes_for :tv
  attr_accessible :tv_attributes
end

class Tv 
  belongs_to :user
  attr_accessible :manufacturer
  validates_presence_of :user
end

Notice that Tv's user is not accessible on purpose. So you have a tripple-nested form that allows you to enter house, rooms, and tvs on one page.

Here's the controller's create method:

def create
  @house = House.new(params[:house])

  if @house.save
    # ... standard stuff
  else
    # ... standard stuff
  end
end

Question: How in the world would you populate user_id for each tv (it should come from current_user.id)? What's the good practice?

Here's the catch22 I see in this.

  1. Populate user_ids directly into params hash (they're pretty deeply nested)
    • Save will fail because user_ids are not mass-assignable
  2. Populate user for every tv after #save is finished
    • Save will fail because user_id must be present
    • Even if we bypass the above, tvs will be without ids for a moment of time - sucks

Any decent way to do this?

Max Chernyak
  • 37,015
  • 6
  • 38
  • 43
  • 2
    Thanks for your question. The 'attr_accessible :rooms_attributes' helped me solve a mass-assigned problem with Rails 2.3'S accepts_nested_attributes_for feature. I was getting an error that read 'WARNING: Can't mass-assign these protected attributes: XXX_attributes'. – craig May 30 '10 at 12:43

1 Answers1

2

Anything wrong with this?

def create
  @house = House.new(params[:house])
  @house.rooms.map {|room| room.tv }.each {|tv| tv.user = current_user }
  if @house.save
    # ... standard stuff
  else
    # ... standard stuff
  end
end

I haven't tried this out, but it seems like the objects should be built and accessible at this point, even if not saved.

Matt Van Horn
  • 1,654
  • 1
  • 11
  • 21