1

我有一个奇怪的问题。

我有两个模型用户和角色,它们之间存在多对多关系。我想在用户的角色集合中过滤名称为“管理员”的角色。

在模型中此代码

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 方法中,因此在保存用户之前执行。

4

1 回答 1

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
于 2012-01-23T22:09:54.977 回答