Billy Gray
2009-Aug-21  16:37 UTC
Getting :accepts_nested_attributes_for to work with a :belongs_to relationship
Hi Rails hackers,
I just recently came across the fantastic new
accepts_nested_attributes_for method off Ryans Scraps, checked out the
Rails blog announcement of the feature in 2.3, watched the Rails Cast,
etc.
I''m trying to work it into an app where the signup form is for an
Account model with a nested Owner object, which is actually a User
object, hooked in via belongs_to instead of one of the has_*
associations. I would think this would work using the new features,
but I can''t seem to get past setting up the new form properly. I
cannot find any documentation or examples out there that show the
proper way to do this, so I figured I''d ask, I can''t imagine
no one
else is trying to do this.
Here are the two models involved:
  class Account < ActiveRecord::Base
    # Relationships
    belongs_to :owner, :class_name => ''User'', :foreign_key
=>
''owner_id''
    accepts_nested_attributes_for :owner
    has_many :users
  end
  class User < ActiveRecord::Base
    belongs_to :account
  end
I have a suspicion that the fact that a user can have an account via
the account :has_many users might be tripping up whatever sets up the
relationship for owner (user) over the belongs_to.
This is the view code in new.html.haml:
  - form_for :account, :url => account_path do |account|
    = account.text_field :name
    - account.fields_for :owner do |owner|
      = owner.text_field :name
And this is the controller code for the new action:
  class AccountsController < ApplicationController
    # GET /account/new
    def new
      @account  = Account.new
    end
  end
When I try to load /account/new I get the following exception:
  NameError in Accounts#new
  Showing app/views/accounts/new.html.haml where line #63 raised:
  @account[owner] is not allowed as an instance variable name
If I try to use the mysterious ''build'' method, it just bombs
out in
the controller:
  class AccountsController < ApplicationController
    # GET /account/new
    def new
      @account  = Account.new
      @account.owner.build
    end
  end
  You have a nil object when you didn''t expect it!
  The error occurred while evaluating nil.build
If I try to set this up using @account.owner_attributes = {} in the
controller, or @account.owner = User.new, I''m back to the original
error, "@account[owner] is not allowed as an instance variable name".
Does anybody have the new accepts_nested_attributes_for method working
with a belongs_to relationship?
Many thanks for any guidance,
Billy