我是Rails 3的新手,无法在Join表中保存记录。我一直在环顾四周,尝试在本网站和文档或书籍中找到不同的例子,但我不明白为什么我不能让它工作。我试图通过创建角色并将它们与用户关联来创建授权。到目前为止,我一直在尝试从用户控制器中的更新操作分配角色而不占优势。
我有3个模型:User.rb,role.rb和assignment.rb(连接表)
class User < ActiveRecord::Base
has_many :assignments, :dependent => :destroy
has_many :roles, :through => :assignments, :foreign_key => :role_id
accepts_nested_attributes_for :roles
attr_accessor :password, :role_ids
attr_accessible :first_name, :last_name, :email, :password, :password_confirmation, :status, :description, :username, :roles_attributes
...
end
class Role < ActiveRecord::Base
has_many :assignments
has_many :users, :through => :assignments, :foreign_key => :user_id
accepts_nested_attributes_for :users
attr_accessible :name
end
class Assignment < ActiveRecord::Base
belongs_to :user
belongs_to :role
accepts_nested_attributes_for :roles
end
更新操作中的用户控制器我有以下
class UsersController < ApplicationController
...
def update
@user = User.find(params[:id])
if @user.update_attributes(params[:user])
@user.roles.build
flash[:success] = "Profile updated"
redirect_to @user
else
@title = "Edit" + " " + @user.username
render 'edit'
end
end
...
end
并且在“编辑”视图页面中,我打算使用复选框来更新具有关联角色的用户记录:
编辑:将“check_box”更改为“check_box_tag”...复选框显示正确,但未保存值。
<%= form_for(@user) do |f| %>
...
<div class="field">
<%= f.label :roles %><br />
<%= f.fields_for :role_ids do |r| %>
<% @roles.each do |role| %>
<%= check_box_tag "user[roles][]", role.id, @user.roles.include?(role.id) %>
<%= role.name %>
<% end %>
<%= hidden_field_tag "user[roles][]", "" %>
<% end %>
</div>
<% end %>
使用此代码,我甚至会收到“角色”没有关联的错误。
编辑:使用accepts_nested_attributes_for :role
更正了此问题。谢谢!
找不到名称`roles'的关联。它已被定义了吗?
我真的很困惑我做错了什么。非常感谢您的帮助。
的Aurelien
答案 0 :(得分:2)
您必须在定义关联时使用与“accepts_nested_attributes_for”相同的名称:
class Assignment < ActiveRecord::Base
belongs_to :user
belongs_to :role
accepts_nested_attributes_for :role
end
答案 1 :(得分:0)
最后解决了我可以分享的问题和想法。
模型关联,但我确实更改了attr_accessible:
class User < ActiveRecord::Base
has_many :assignments, :dependent => :destroy
has_many :roles, :through => :assignments, :foreign_key => :role_id
accepts_nested_attributes_for :roles
attr_accessor :password
attr_accessible ..., :roles_ids
...
end
在编辑和更新操作的用户控制器中。
def edit
@title = "Edit" + " " + @user.username
@roles = Role.find(:all)
@user.assignments.build
end
def update
@user = User.find(params[:id])
if @user.update_attributes(params[:user])
flash[:success] = "Profile updated"
redirect_to @user
else
@title = "Edit" + " " + @user.username
render 'edit'
end
end
重要的部分是视图部分,并为复选框标记
指定正确的名称<%= form_for(@user) do |f| %>
<div class="field">
<%= f.label :roles %><br />
<%= f.fields_for :role_ids do |r| %>
<% @roles.each do |role| %>
<%= check_box_tag "user[role_ids][]", role.id, @user.roles.include?(role) %>
<%= role.name %>
<% end %>
<%= hidden_field_tag "user[role_ids][]", @user.id %>
<% end %>
</div>
check_box_tag
让表单保存数组并提供比check_box
更多的控制权
然后,为了分配多个角色ID,check_box_tag的名称应包含user[roles_ids][]
。
最后,如果用户已经有角色,check_box_tag的最后一个参数将返回,如果为true,则选中复选框。
我必须承认check_box_tags的名称部分确实令人困惑,但它有效:)。