0

次のクラスがある場合

class User
    has_many :documents
end

class Document
    belongs_to :user
end

私は次のことができるようにしたいと思います

User.where("id > 200").documents

次のようなSQLを生成する必要があります

select * from documents
join users on documents.user_id == users.id
where users.id > 200

しかし、activerecord はそれほど賢くはありません。これは、箱から出してすぐに可能であると期待するのは不合理ですか?

== 考えられるアンチ DRY ソリューション ==

class User
    has_many :documents
    def self.documents
        Documents.joins(:users).merge(self.scoped)
    end
end

しかし、これは私がすでに定義した関係を複製しているように見えるので、あまり DRY ではありません。

4

3 に答える 3

1

いいえ、ActiveRecord ではできません。経験則 - メソッドの呼び出しを開始するクラスは、オブジェクトが返されるクラスです。したがって、 User.whatever を実行すると、常に User オブジェクトが返されます。これにより、必要なことを行う可能性がほとんどなくなります。

Document オブジェクトを取得したい場合は、代わりに Document クラスでそれらのクエリを開始する必要があります。User モデルでユーザー固有のスコープをいつでも定義し、DRY のために Document モデルでそれらを再利用できます。

class User < ActiveRecord::Base
  scope :foo, where("users.id > 200")
end

class Document < ActiveRecord::Base  
  belongs_to :user

  scope :bar, joins(:user).merge(User.foo)  
end

これにより、Document モデルで User で定義された (およびユーザー固有の) スコープを効果的に使用できます。また、 User.where("id > 200").documents は Document.where("users.id > 200") よりも意味がないと主張します (結合は意図的にスキップされました)。

したがって、個人的には、あなたはこの問題に間違った方向からアプローチしようとしているだけだと思います:)

于 2012-07-03T07:28:23.627 に答える
0

サンプルクラスの場合、テーブルのuser_idフィールドをクエリするだけです 。documents

Document.where("user_id > 200")
于 2012-07-03T07:38:57.233 に答える
0

これを試して:

Document.joins(:user).where('user.id > ?', 200)
于 2012-07-03T06:59:49.687 に答える