0

次の機能スニペットを考えると、データベース クエリを減らすのに問題があります。

class User < ApplicationRecord
  belongs_to :account

  def self.do_something
    self.find_each do |user|
      puts "#{self.new.account.name}:#{user.name} did something"
    end
  end
end

class Account < ApplicationRecord
  has_many :users
end

a = Account.first
puts 'starting'
a.users.do_something

アカウントの負荷 (0.4ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]

起動

アカウントの負荷 (0.3ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]

テスト:ユーザーが何かをした

アカウントの負荷 (0.3ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]

テスト:ユーザーが何かをした

アカウントの負荷 (0.3ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]

テスト:ユーザーが何かをした

アカウントの負荷 (0.3ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]

テスト:ユーザーが何かをした

Account モデルがユーザーごとにデータベースから取得されていることがわかります。

元のアカウントを参照するために Singleton メソッドのようなものを使用したいと思ってself.accountいましたが、デフォルトでは明らかに関係が存在しないため、現在 を使用していself.new.accountます。

a内部から保存された元の Account モデルを取得できる場所は他にありself.do_somethingますか? 明らかにアカウントをパラメータに渡すことができますが、特に後で引数を追加する場合は面倒です...

4

1 に答える 1

0

ループ内find_eachでは、 を使用できるはずですuser.account

そのループの外では、オブジェクトを見つけるための文書化/サポート/警告なしで消えない方法があるとは思いません。Rails のバージョンによっては、self.current_scope.proxy_association.owner必要な答えが得られる可能性がありますが、user.account可能な限り優先してください。プライベート API を使用すればするほど、将来のアップグレードが難しくなる可能性があります。


または、関連拡張機能do_somethingを使用して、関連内でのみメソッドを定義することを検討してください。 orhas_manyとして呼び出すのに適していない場合(関連する を持たないため)、最終的にトップレベルのメソッドであってはならない可能性があります。User.do_somethingUser.where(name: "Bob").do_somethingaccount

于 2018-06-21T13:00:33.850 に答える