我有一个奇怪的问题。
我有两个模型用户和角色,它们之间有多对多的关系。 我想在用户的角色集合中过滤名为“Administrator”的角色。
在模型中这段代码
puts self.roles.to_s
打印到屏幕: [角色ID:1,名称:“管理员”,created_at:“2012-01-22 21:55:45”,updated_at:“2012-01-22 21:55:45”]
但是这段代码
puts self.roles.find_by_name('Administrator').to_s
不打印任何内容。这一个:
puts self.roles.find_by_name('Administrator').nil?
打印为真!
为什么我的find_by_name方法不起作用? 我在控制台试了它,效果很好。
我的代码段如下:
puts self.roles.to_s
puts self.roles.find_by_name('Administrator').to_s
puts self.roles.find_by_name('Administrator').nil?
输出如下:
[Role id: 1, name: "Administrator", created_at: "2012-01-22 21:55:45", updated_at: "2012-01-22 21:55:45"]
<none>
true
我做错了什么?它必须是愚蠢的东西。 此代码位于validate方法中,因此在保存用户之前执行。
答案 0 :(得分:3)
您提到您在保存模型之前在验证中执行此操作。这就是它失败的原因。由于User
尚未保存,因此数据库中没有id
,因此无法搜索您的关联。
第一行的工作原因(self.roles.to_s
)是Rails会记住您添加到用户的任何角色,但在保存用户之前不会将它们保存到数据库中。保存用户后,您的第二行/第三行将正常工作:
user = User.new
user.roles << Role.first
user.roles
# => [#<Role id: 1, name: "Administrator" ...>]
user.roles.find_by_name("Administrator")
# => nil
user.save # This inserts both the new user AND the associations
user.roles.find_by_name("Administrator")
# => #<Role id: 1, name: "Administrator" ...>
如果您必须在验证中使用此功能,则可以尝试使用Enumerable的find
方法来搜索roles
数组:
user = User.new
user.roles << Role.first
user.roles
# => [#<Role id: 1, name: "Administrator" ...>]
user.roles.find { |role| role.name == "Administrator" }
# => #<Role id: 1, name: "Administrator" ...>
user.roles.find { |role| role.name == "Foo" }
# => nil