2012-04-23 11 views
1

私は、ユーザーの時間レコードのセットを取得しようとしています。クエリは、パブリック(すなわちプライベート== false)またはプライベート(すなわちプライベート== true)のいずれかであり、その時間のスロットレコードを有するレコードをネットワークに返すべきである。オプションの結合を使用してレコードを取得するにはどうすればよいですか?

私はActiveRecordでこれをやりたいのですが、私が見つけた唯一の方法は2つの別々のクエリを実行することです。それは、結果がチャージングなどを防止するActiveRecordリレーションではなく配列であることを除いては問題ありません。

何か提案がありますか?

class TimeAccessPolicy 
    attr_reader :network 

    def initialize(network) 
    @network = network 
    end 

    def accessible_times_for(user) 
    return [] unless user.is_member_of?(network) 
    times = network.times.where(private: false) 
    times + network.times.joins(:slots).where(private: true, slots: {user_id: user.id}) 
    end 
end 

- 編集:

class Time < ActiveRecord::Base 
    belongs_to :network 
    has_many :slots 
    has_many :participants, through: :slots, source: :user 

    # has private boolean 
    ... 
end 

class Network < ActiveRecord::Base 
    has_many :memberships, as: :memberable, dependent: :destroy 
    has_many :users, through: :memberships 
    has_many :times 

    ... 
end 

class Slot < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :time 

    ... 
end 
+0

あなたが少しを投稿できるんより多くの文脈、私あなたのモデルにいくつかのスコープを追加したいと思っています。ネットワークモデルを投稿し、時刻がどこから来ているかを説明します。ネットワークモデルでhas_many関係ですか? 「ActiveRecord関係を維持する」と聞くとすぐに、私はスコープについて考える。 – RadBrad

答えて

1

あなたはこのようにscoped method

を使用することができます。

times = network.times.scoped 
# times is still ActiveRecord relation 
if private 
    times = times.joins(:slots).where(private: true, slots: {user_id: user.id}) 
else 
    times = times.where(private: false) 
end 

このコード一つだけのクエリ

関連する問題