本文介绍了复杂形式-以单一形式管理多个模型-(三度疯狂)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已在下面的第二段代码中隔离了该问题(如果您不想要所有详细信息):我可以从帐户模型中创建新用户.我无法从帐户模型中分配这些用户角色.我正在使用fields_for,当我尝试将role_ids分配给角色模型时,此方法不起作用.我的数据库是通过以下方式设置的:

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:

  1. 帐户模型has_many:用户

用户模型has_and_belongs_to_many:角色,归属地址:帐户

User model has_and_belongs_to_many :roles,belongs_to :accounts

角色模型has_and_belongs_to_many:用户

Roles model has_and_belongs_to_many :users

views/accounts/new.html.erb

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行上的#的未定义方法'roles'",如下所示:

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 }

consol的@ accounts.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">]
>> 

推荐答案

您应该使用accepts_nested_attributes_for,因此在模型中:

You should use accepts_nested_attributes_for, so in models:

# Account model
accepts_nested_attributes_for :users

# User model
accepts_nested_attributes_for :roles

然后应删除user_attributes=role_attributes=方法.
您的表单应如下所示:

Then you should remove user_attributes= and role_attributes= methods.
Your form should look like this:

<% form_for @account do |f| %>
   <% fields_for :users do |u| %>
      ... # user fields
      <% fields_for :roles do |r| %>
         ... # role fields
      <% end %>
   <% end %>
   <%= f.submit 'Save' %>
<% end %>

它将自动迭代与帐户关联的所有用户以及与该用户关联的所有角色.

It will automaticaly iterate over all users associated with account and all roles associated with user.

有关更多详细信息,请阅读这里.

For more details read here.


您可以在控制器中为用户分配角色:


You can assign roles to user, in controller:

role = Roles.find(some_id)
@user.roles << role

@user.role_ids = [2, 4, 6]

但是我不确定如何使用has_and_belongs_to_many关联添加角色.您正在使用@user.roles.build方法,该方法将创建新角色并将其与用户关联.如果要添加角色,则应使用上面的两个示例之一来完成.但是如何为它创建一个?我不知道.我将为users_roles表添加模型并添加到用户模型:

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 for users_roles table and add to user model:

has_many :users_roles
accepts_nested_attributes_for :users_roles # you should add here also some :reject_if

然后插入fields_for :roles,我将以以下形式添加:

Then insted of fields_for :roles I would add in form:

<% fields_for :users_roles do |ur| %>
  <%= ur.select :role_id, Role.all.collect {|r| [r.name, r.id] }, {:include_blank => true} %>
<% end %>

然后在您的控制器中添加类似3.times { @user.users_roles.build }的内容.如果您想拥有漂亮的添加"和删除"链接来使用javascript创建新角色,请查看这里-这是一个很好的示例.

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.

这篇关于复杂形式-以单一形式管理多个模型-(三度疯狂)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-19 18:55