Rails 3- find_by不工作

时间:2022-08-27 00:10:03

I have a strange problem.

我有一个奇怪的问题。

I have two models Users and roles with a many to many relationships between them. I want to filter the roles with name 'Administrator' within the role collection of a user.

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

In the model this code

在模型中这段代码

puts self.roles.to_s

Prints to screen: [Role id: 1, name: "Administrator", created_at: "2012-01-22 21:55:45", updated_at: "2012-01-22 21:55:45"]

打印到屏幕:[角色ID:1,名称:“管理员”,created_at:“2012-01-22 21:55:45”,updated_at:“2012-01-22 21:55:45”]

But this code

但是这段代码

puts self.roles.find_by_name('Administrator').to_s

doesn't print anything. And this one:

不打印任何东西。和这个:

puts self.roles.find_by_name('Administrator').nil?

prints true!

Why isn't my find_by_name method not working? I tryied it in the console and it works well.

为什么我的find_by_name方法不起作用?我在控制台试了一下,效果很好。

My code snippet is the following:

我的代码段如下:

puts self.roles.to_s
puts self.roles.find_by_name('Administrator').to_s
puts self.roles.find_by_name('Administrator').nil?

And the output is the following:

输出如下:

[Role id: 1, name: "Administrator", created_at: "2012-01-22 21:55:45", updated_at: "2012-01-22 21:55:45"]
<none>
true

What am I doing wrong?? It has to be something stupid. This code is located in a validate method, so it is executed before the user is saved.

我究竟做错了什么??它必须是愚蠢的东西。此代码位于validate方法中,因此在保存用户之前执行。

1 个解决方案

#1


3  

You mentioned that you are doing this in a validation before the model is saved. This is why it's failing. Since the User is not yet saved, it doesn't have an id in your database, so there's no way for it to search your associations.

您提到在保存模型之前,您正在验证中执行此操作。这就是它失败的原因。由于用户尚未保存,因此数据库中没有id,因此无法搜索您的关联。

The reason the first line works (self.roles.to_s) is that Rails memorizes any roles you add to your user, but does not save them to the database until you save the user. Once you save the user, your second/third lines would work fine:

第一行工作的原因(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" ...>

If you have to work with this in your validations, you might try using Enumerable's find method to search the roles array instead:

如果您必须在验证中使用此功能,则可以尝试使用Enumerable的find方法来搜索角色数组:

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

#1


3  

You mentioned that you are doing this in a validation before the model is saved. This is why it's failing. Since the User is not yet saved, it doesn't have an id in your database, so there's no way for it to search your associations.

您提到在保存模型之前,您正在验证中执行此操作。这就是它失败的原因。由于用户尚未保存,因此数据库中没有id,因此无法搜索您的关联。

The reason the first line works (self.roles.to_s) is that Rails memorizes any roles you add to your user, but does not save them to the database until you save the user. Once you save the user, your second/third lines would work fine:

第一行工作的原因(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" ...>

If you have to work with this in your validations, you might try using Enumerable's find method to search the roles array instead:

如果您必须在验证中使用此功能,则可以尝试使用Enumerable的find方法来搜索角色数组:

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