2012-05-24 113 views
0

我有两个型号的Ruby on多重选择与很多Rails的许多关系

项目具有has_and_belongs_to_many:用户

用户具有has_and_belongs_to_many:项目

在项目视图中I有一个表单,其中有一个选择器,我想尝试将多个用户分配给一个项目。

<%= select_tag("project[users]", options_for_select(@users, @project_users), {:multiple=>true, :size=>6})%> 
在我的项目控制器

,它们会在选择中使用的变量是

@project_users = @project.users.collect { |user| user.id} 
@users = User.all.collect { |user| ["#{user.first_name} #{user.last_name}", user.id] } 

所有出看跌

<select id="project_users" multiple="multiple" name="project[users][]" size="6"> 
    <option value="#<User:0x007f567cb7f078>">User1</option> 
    <option value="#<User:0x007f567cb7e9c0>">User2</option> 
</select> 

的问题是,这不是相当于

@some_project << [User(#), User(#)] 

(“注意用户(#)表示类实例”)

而不是它相当于

@some_project << ["1", "2"] 

的问题是用户实例被转换为字符串,但不会再回到实例。

不工作,并会引发错误的

ActiveRecord::AssociationTypeMismatch in ProjectsController#update 
User(#70004716784160) expected, got String(#4266680) 

我怎样才能正确地做这项工作?

+0

在你的'ProjectsController'的更新方法中,你能不能用每个这样的id做一个User.find(user.id),然后从那里建立关联的用户? (这是假设'选项值=“1”'值是用户的ID。) – Zajn

+0

我不认为这是干燥的,看看我是否可以通过格式正确的参数。 –

+0

好点,但它可能会作为临时解决方案,直到你可以找到一个更优雅的。 – Zajn

回答

4

在用户模式:

def full_name 
    [first_name, last_name].join(" ") 
end 

在你的控制器

@users = User.all 

在你看来:

<%= select_tag('project[user_ids]', options_from_collection_for_select(@users, 'id', 'full_name'), { :multiple => true, :size => 6 }) %> 

然后,你可以使用

@project.user_ids = params[:project][:user_ids] 

@project.update_attributes(params[:project]) 

用于分配。

+0

这将导致ActiveRecord :: AssociationTypeMismatch,因为参数是字符串。这是我已经在做的事情。尽管你清理了我的选择标记代码:) 问题是我需要将字符串转换回更新的实例然后手动分配。 –

+0

这应该不是问题,因为project.user_ids需要id,而不是记录(我相信他们会将它们转换为整数['5'到5])。如果你尝试去做project.users = params [:project] [:user_ids],你会得到一个类型不匹配,但是如果你设置了project.user_ids,那就不会有问题。 –

+0

你的权利,我没有意识到,user_ids是一种方法,很好。 –

2

您无法发送实例。它可以在表单的呈现和提交之间切换。转换为字符串是单向操作,因为它引用对象的唯一标识(如内存地址),而不是属性或数据库标识符!因为它不是ActiveRecord的一部分,而是Ruby的对象库。当表单的数据被返回时,实例不在内存中,因此无法将其转换回来,即使其他情况下也是如此。

坚持到普通的老办法:

@project_users = @project.users.collect { |user| user.id} 
@users = User.all.collect { |user| ["#{user.first_name} #{user.last_name}", user.id] } 

并将数据提交时:

@users = params[:project][:users].map{|a| User.find(a) } 
+1

我最终在我的更新中使用了这个ID users = User.where(id:params [:user_ids]) @ project.users = users –

+0

好,但重点是,你不能序列化实例放入字符串中,然后像读过的那样读回来。 – Matzi

+0

正确的是这一点。 –