复杂的形式 - 以单一形式管理多个模型 - (三级疯狂)
我已在下面的第二个代码块中隔离了问题(如果您不需要所有详细信息):我可以从帐户模型创建新用户。我无法从帐户模型分配这些用户角色。我正在使用 fields_for,当我尝试将 role_ids 分配给角色模型时,此方法不起作用。我的数据库按以下方式设置:
帐户模型 has_many :用户
用户模型 has_and_belongs_to_many :角色, belongs_to:帐户
角色模型has_and_belongs_to_many:用户
views/accounts/new.html.erb
<% for user in @account.users %>
<% fields_for "account[user_attributes][]", user do |account_fields| %>
<p>Login : <%= account_fields.text_field :login %>
<p>Email : <%= account_fields.text_field :email %>
<p>Password : <%= account_fields.password_field :password %>
<p>Confirm Password : <%= account_fields.password_field :password_confirmation %>
<%= account_fields.hidden_field :account_id, :value => :id %>
<% end %>
<% end %>
<% for role in @account.users.first.roles %>
<% fields_for "account[role_attributes]]", role do |role_fields| %>
<%= role_fields.hidden_field :role_ids, :value => '[1]' %>
<% end %>
<% end%>
account.rb 模型中的关联 setter 方法:使用堆栈跟踪,我已将问题隔离到第 34 行的“# 的未定义方法`角色”,标记如下:
def user_attributes=(user_attributes)
user_attributes.each do |attributes|
users.build(attributes)
end
end
def role_attributes=(role_attributes)
role_attributes.each do |attributes|
users.roles.build(attributes) #error here (stacktrace)
end
end
最后,在帐户控制器中,我在内存中构建了用户和角色:
def new
@account = Account.new
1.times { @account.users.build }
1.times { @account.users.first.roles.build }
来自 consol 的 @accounts.users.first.roles.build 证明:
>> account
=> #<Account id: 1, subdomain: "justinzollars", created_at: "2010-02-08 14:41:13", updated_at: "2010-02-08 14:41:13">
>> account.users
=> [#<User id: 13, login: "jayz", email: "[email protected]", crypted_password: "f9a3d618fc650d285a90f9775508c13784891b97", salt: "f497a7dd909b695caff1f6310e710245615d55b6", created_at: "2010-02-08 20:25:48", updated_at: "2010-02-08 20:25:48", remember_token: nil, remember_token_expires_at: nil, account_id: 1>, #<User id: 16, login: "jasonwade23", email: "[email protected]", crypted_password: "06581b47cfac7a529773d61dc0b1d5d6c0da6c08", salt: "93f8b99cd9da60b904d553fcc7843bfb66352c3e", created_at: "2010-02-13 07:46:14", updated_at: "2010-02-13 07:46:14", remember_token: nil, remember_token_expires_at: nil, account_id: 1>]
>> account.users.first
=> #<User id: 13, login: "jayz", email: "[email protected]", crypted_password: "f9a3d618fc650d285a90f9775508c13784891b97", salt: "f497a7dd909b695caff1f6310e710245615d55b6", created_at: "2010-02-08 20:25:48", updated_at: "2010-02-08 20:25:48", remember_token: nil, remember_token_expires_at: nil, account_id: 1>
>> account.users.first.roles
=> [#<Role id: 1, name: "admin">, #<Role id: 2, name: "alt">]
>>
I have isolated the problem in the second block of code below (if you don't want all the details): I can create new users from the account model. I can't assign those users roles from the accounts model. I am using fields_for, this method does not work when I attempt to assign the role_ids to the roles model. My db is set up in the following way:
Account model has_many :users
User model has_and_belongs_to_many :roles,
belongs_to :accountsRoles model has_and_belongs_to_many :users
views/accounts/new.html.erb
<% for user in @account.users %>
<% fields_for "account[user_attributes][]", user do |account_fields| %>
<p>Login : <%= account_fields.text_field :login %>
<p>Email : <%= account_fields.text_field :email %>
<p>Password : <%= account_fields.password_field :password %>
<p>Confirm Password : <%= account_fields.password_field :password_confirmation %>
<%= account_fields.hidden_field :account_id, :value => :id %>
<% end %>
<% end %>
<% for role in @account.users.first.roles %>
<% fields_for "account[role_attributes]]", role do |role_fields| %>
<%= role_fields.hidden_field :role_ids, :value => '[1]' %>
<% end %>
<% end%>
Associated setter methods in the account.rb model: using the stacktrace I have isolated the problem to "undefined method `roles' for #" on line 34, marked below:
def user_attributes=(user_attributes)
user_attributes.each do |attributes|
users.build(attributes)
end
end
def role_attributes=(role_attributes)
role_attributes.each do |attributes|
users.roles.build(attributes) #error here (stacktrace)
end
end
finally, within the accounts controller I build the users and roles in memory:
def new
@account = Account.new
1.times { @account.users.build }
1.times { @account.users.first.roles.build }
The @accounts.users.first.roles.build proof from consol:
>> account
=> #<Account id: 1, subdomain: "justinzollars", created_at: "2010-02-08 14:41:13", updated_at: "2010-02-08 14:41:13">
>> account.users
=> [#<User id: 13, login: "jayz", email: "[email protected]", crypted_password: "f9a3d618fc650d285a90f9775508c13784891b97", salt: "f497a7dd909b695caff1f6310e710245615d55b6", created_at: "2010-02-08 20:25:48", updated_at: "2010-02-08 20:25:48", remember_token: nil, remember_token_expires_at: nil, account_id: 1>, #<User id: 16, login: "jasonwade23", email: "[email protected]", crypted_password: "06581b47cfac7a529773d61dc0b1d5d6c0da6c08", salt: "93f8b99cd9da60b904d553fcc7843bfb66352c3e", created_at: "2010-02-13 07:46:14", updated_at: "2010-02-13 07:46:14", remember_token: nil, remember_token_expires_at: nil, account_id: 1>]
>> account.users.first
=> #<User id: 13, login: "jayz", email: "[email protected]", crypted_password: "f9a3d618fc650d285a90f9775508c13784891b97", salt: "f497a7dd909b695caff1f6310e710245615d55b6", created_at: "2010-02-08 20:25:48", updated_at: "2010-02-08 20:25:48", remember_token: nil, remember_token_expires_at: nil, account_id: 1>
>> account.users.first.roles
=> [#<Role id: 1, name: "admin">, #<Role id: 2, name: "alt">]
>>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该使用
accepts_nested_attributes_for
,因此在模型中:那么您应该删除
user_attributes=
和role_attributes=
方法。您的表单应如下所示:
它将自动迭代与帐户关联的所有用户以及与用户关联的所有角色。
有关更多详细信息,请阅读此处< /a>.
编辑:
您可以在控制器中将角色分配给用户:
或
但是我不确定如何使用
has_and_belongs_to_many
关联添加角色。您正在使用@user.roles.build
方法,该方法将创建新角色并将其与用户关联。如果您想添加角色,您应该使用上面两个示例之一来执行此操作。但如何为它创建一个 from 呢?我不知道。我会为users_roles
表添加一个模型并添加到用户模型:然后插入
fields_for :roles
我会在表单中添加:然后在您的控制器中,您应该添加类似 <代码>3.times { @user.users_roles.build }。如果您想要使用 javascript 为您创建新角色的“添加”和“删除”链接,请查看 这里 - 这是如何处理它的很好的例子。
You should use
accepts_nested_attributes_for
, so in models:Then you should remove
user_attributes=
androle_attributes=
methods.Your form should look like this:
It will automaticaly iterate over all users associated with account and all roles associated with user.
For more details read here.
EDIT:
You can assign roles to user, in controller:
or
However I'm not sure how to add roles with
has_and_belongs_to_many
association. You are using@user.roles.build
method which will create new role and associate it with user. If you want to add a role you should do it with one of two examples above. But how to create a from for it? I don't know. I would add a model forusers_roles
table and add to user model:Then insted of
fields_for :roles
I would add in form:Then in your controller you should add something like
3.times { @user.users_roles.build }
. If you want to have nice "Add" and "Remove" links that create for you new role with javascript, take a look here - it is really nice example how to handle it.