1

奇妙な問題があります。

私には2つのモデルのユーザーと役割があり、それらの間には多対多の関係があります。ユーザーのロールコレクション内で「Administrator」という名前のロールをフィルタリングしたいと思います。

モデルでは、このコード

puts self.roles.to_s

画面に出力:[ロールID:1、名前: "Administrator"、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 がユーザーに追加したロールを記憶しますが、ユーザーを保存するまでロールをデータベースに保存しないためです。ユーザーを保存すると、2 行目または 3 行目が正常に機能します。

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 に答える