Rails 3- find_by不工作

时间:2012-01-23 20:16:52

标签: ruby ruby-on-rails-3 activerecord findby

我有一个奇怪的问题。

我有两个模型用户和角色,它们之间有多对多的关系。 我想在用户的角色集合中过滤名为“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方法中,因此在保存用户之前执行。

1 个答案:

答案 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