不知道有多少人跟我一样在这里载坑了
本来是想用 accepts_nested_attributes_for 写一个 nested form
class User < ActiveRecord::Base
attr_accessible :email, :account_attributes
has_one :account
accepts_nested_attributes_for :account
end
class Account < ActiveRecord::Base
attr_accessible :password, :password_confirmation
has_secure_password
belongs_to :user
end
class UsersController < ApplicationController
def new
@user = User.new
end
end
view 里
<%= form_for @user do |f| %>
email: <%= f.text_field :name %>
<%= f.fields_for :account do |account_form| %>
password: <%= account_form.password_field :password %>
password_confirmation: <%= account_form.password_field :password_confirmation %>
<% end %>
<% end %>
一开始无法显示 account 里的内容,后来发现没有在 controller 里 build account, 于是
class UsersController < ApplicationController
def new
@user = User.new
@user.account.build
end
end
报错 undefined method `build' for nil:NilClass
刚开始怎么也想不通,隔了一天去翻http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html 才发现原来 has_one 的 build 方法是 build_association 而不是 collection.build。因为不常用 has_one,rails 里“约定”又比较多,才会当 has_many 的方法来写。
把 controller 里改成
class UsersController < ApplicationController
def new
@user = User.new
@user.build_account
end
end
程序才正常跑起来
一言蔽之 在 has_many 中:User#accounts.build 在 has_one 中:User#build_account