2010-03-13 2 views
2

내 사용자 모델은 동일한 메시지 모델에 대해 세 가지 관계가 있으며 원시 SQL을 사용합니다./동일한 결과를 얻으려면 더 나은 레일 방법이 있습니까?리 트랙터링 고급 has_many 예제

외래 키를 동적으로 변경할 수 있습니까? 예 : User.messages.sent (외래 키 = author_id) 및 User.messages.received (외래 키 =받는 사람) 일부 논리를 메시지 모델의 범위로 이동하려고 시도했지만 user.id를 사용할 수 없습니다. 메시지 모델 ...

어떤 생각?

테이블 레이아웃 :

create_table "messages", :force => true do |t| 
    t.string "subject" 
    t.text  "body" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    t.integer "author_id" 
    t.integer "recipient_id" 
    t.boolean "author_deleted", :default => false 
    t.boolean "recipient_deleted", :default => false 
    end 

이 내 사용자 모델에 대한 나의 관계입니다 :

has_many :messages_received, :foreign_key => "recipient_id", :class_name => "Message", :conditions => ['recipient_deleted = ?', false] 
    has_many :messages_sent, :foreign_key => "author_id", :class_name => "Message", :conditions => ['author_deleted = ?', false] 
    has_many :messages_deleted, :class_name => "Message", :finder_sql => 'SELECT * FROM Messages WHERE 
                     author_id = #{self.id} AND author_deleted = true OR 
                     recipient_id = #{self.id} AND recipient_deleted = true' 

감사합니다. 추가 정보

답변

3

예, 삭제 된 메시지와 삭제되지 않은 메시지를 정렬하려면 named_scope을 사용하십시오.

class User < ActiveRecord::Base 
    has_many :messages_received, :foreign_key => 'recipient_id' 
    has_many :messages_sent, :foreign_key => 'author_id' 
end 

class Messages < ActiveRecord::Base 
    named_scope :deleted, :conditions => 'author_deleted = TRUE OR recipient_deleted = TRUE' 
    named_scope :not_deleted, :conditions => 'author_deleted = FALSE OR recipient_deleted = FALSE' 
end 

# Example user 
user = User.first 
user.messages_received.deleted 
user.messages_received.not_deleted 
user.messages_sent.deleted 
user.messages_sent.not_deleted 

다른 방법으로는 한 단계 더 나아가 외국 키로 user_id를 사용하여 메시지 유형을 지정하여 연결을 simplfy 수 있습니다.

  1. 한 적은 열 :

    create_table "messages", :force => true do |t| 
        t.string "subject" 
        t.text  "body" 
        t.datetime "created_at" 
        t.datetime "updated_at" 
        t.string "message_type" 
        t.integer "user_id" 
        t.boolean "deleted", :default => false 
    end 
    
    class User < ActiveRecord::Base 
        has_many :messages 
    end 
    
    class Messages < ActiveRecord::Base 
        MESSAGE_TYPES = %w[Recipient Author] 
    
        belongs_to :user 
    
        named_scope :recipient, :conditions => {:message_type => 'Recipient'} 
        named_scope :author, :conditions => {:message_type => 'Author'} 
        named_scope :deleted, :conditions => {:deleted => true} 
        named_scope :not_deleted, :conditions => {:deleted => false} 
    
        # Convenience class methods 
        def self.sent 
        author.not_deleted 
        end 
    
        def self.received 
        recipient.not_deleted 
        end 
    end 
    
    # Example usage 
    user = User.first 
    user.messages.sent 
    user.messages.received 
    user.messages.deleted 
    

    이 방법은 advantagoues 때문이다.

  2. 확장 가능. 앞으로 추가 메시지 유형을 추가하는 것은 간단합니다 (예 : 임시 보관함).
+0

감사합니다. 현재 각 메시지에 대해 하나의 레코드 만 있습니다. 귀하의 두 번째 예제를 통해 나는 각 메시지를 보낼 두 개의 메시지를 만들어야 할 것입니다. (작성자와 수신자) 여러 명의 수신자 등을 보내고 회신하는 것이 가능하기 때문에 실제로는 더 좋은 디자인 일 수 있습니다. 중복되는 제목/메시지. 나는 삭제 된 모든 메시지를 표시하고 단일 쿼리로 보내거나받을뿐만 아니라 어떻게 표시하는지 궁금합니다. @trash = user.messages.sent.deleted + user.messages.received.deleted – atmorell

+0

'named_scope'는 체인 가능합니다. 삭제 된 모든 메시지를 보여주고 싶다면'user.messages.deleted' 명령을 보내고 보내거나받을 메시지를 제한하지 않아도됩니다. –

+0

알겠습니다. 고맙습니다. – atmorell