質問

私はレールで初心者ですとMySQLに参加左を実行しようとします。

ユーザーとメッセージ -

2つのオブジェクトが存在します。

ユーザーhas_and_belongs_to_manyアソシエーションメッセージ、メッセージhas_and_belongs_to_manyアソシエーションのユーザー

現在、単にuser.messagesを書き込むことによって、私は、コンソールでクエリを以下の取得

SELECT * FROM `messages` INNER JOIN `messages_users` ON `messages`.id = `messages_users`.message_id WHERE (`users_messages`.group_id = 1 )

== falseはなく、任意のユーザーに接続していないれる制限されたとのメッセージが任意のユーザによってアクセス可能であり、そして私は、コレクションMessage.allを追加する必要がありuser.messagesに(=> falseの制限)

私の問題を解決するクエリは以下のようになります:

select * from messages left join messages_users on messages_users.message_id=messages.id and messages_users.user_id=1 where (messages_users.user_id is NULL and messages.restricted=false) OR (messages_users.user_id=1 and messages.restricted=true);

私は、できるだけエレガントレールでそれを書くのですか?

は、

のようになめらかになります
Message.find(:all,:conditions => "(messages_users.user_id is NULL and messages.restricted=false) OR (messages_users.user_id=1 and messages.restricted=true)", :joins => "left join messages_groups on messages_users.message_id=messages.id and messages_users.user_id=1 " )

またはそれがよりよいすることができますか?

私が使用しているレール2.3.2

おかげで、 パベル

役に立ちましたか?

解決

。1)すべてのメッセージが制限=偽及び2)と、現在のユーザーに関連付けられたすべてのメッセージ制限=真あなたがそのクエリに二つのことを引っ張るしようとしているように私には思えます>

私は正しくそれを理解していた場合、私はあなたはそれが単一のクエリとして行わたい場合は、それを行うには良い方法が表示されません。あなたはそれの2つのクエリを作るというアイデアに開いている場合(おそらく実行速度を遅くしながら)しかし、あなたは、コード内で少しそれをクリーンアップすることができます。ここで代替の設定は次のとおりです。

class Message < ActiveRecord:Base
  has_and_belongs_to_many :users

  named_scope :restricted, :conditions => {:restricted => true}
  named_scope :unrestricted, :conditions => {:restricted => false}
  named_scope :public, :conditions => "id NOT IN (SELECT DISTINCT message_id FROM messages_users)"
end

class User < ActiveRecord:Base
  has_and_belongs_to_many :messages
end

以下のコード内のリストを取得しますが、2つのデータベースを必要とするヒットにあなたが行うことができます:

@current_user.messages.restricted + Message.unrestricted.public

のいずれかの場合には、あなたは彼らが適切にインデックス化されているか、これは任意の負荷を遅くしようとしていることを確認する必要があり、これらのテーブル内のデータの実質的な量があるかどうか。これは送信されたメッセージの多くのアプリであれば、あなたはおそらく、単一のクエリとの方がいいでしょう。それはあまり使用されないだけでサイド関数の場合、私はおそらくクリーンバージョンを取るだろう。

どのようなおそらくモデルの観点から、より良い仕事とは、HABTM関係を取り除くと、明示的な関係をモデル化することです。その後、メッセージの送信/配信/(ETC送ら時間、時間の読み取りを、追跡のような)受信処理に関する他のデータを追跡するための便利な場所を持っています。それは私がちょうどHABTMに至るまで、多くを持っていることを好む、上記の議論のいずれかを変更しません。

class Message < ActiveRecord:Base

  has_many :subscriptions
  has_many :users, :through => :subscriptions

  named_scope :restricted,   :conditions => {:restricted => true}
  named_scope :unrestricted, :conditions => {:restricted => false}
  named_scope :public, :conditions => "id NOT IN (SELECT DISTINCT message_id FROM subscriptions)"
end

class User < ActiveRecord:Base

  has_many :subscriptions
  has_many :messages, :through => :subscriptions

end

class Subscription < ActiveRecord:Base

  belongs_to :message
  belongs_to :user

end

他のヒント

は使用しない理由は?含める

私はnamed_scopesは、あなたの答えかもしれないと思います。お使いのモデルのようなものを入れます:

named_scope :restricted,   :conditions => {:restricted => true}
named_scope :unrestricted, :conditions => {:restricted => false}

次に、あなたのようなものを呼び出すことができます

Message.restricted
=> All restricted messages

User.first.messages.unrestricted
=> All unrestricted messages belonging to the first user.

私はHABTM団体を介してこれらの作業を信じています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top