我如何使用Rails找到一个has_many而不是另一个?

时间:2011-06-24 22:34:17

标签: ruby-on-rails has-many

消息has_many user_messages。它有两个。

1 UserMessage将发件人设为user_id

其他UserMessage将接收者设为user_id

了解一个用户,对于任何消息,我该如何找到另一个用户?

这是我尝试作为Message类的方法,但它失败了:

 32   def other_user(one_user)      
 33     um = self.user_messages
 34     um.each do |user_message|
 35       
 36       output_user = User.find(user_message.user_id) unless user_message.user_id == one_user.id
 37     end
 38     
 39     return output_user
 40   end

2 个答案:

答案 0 :(得分:1)

似乎应该更好地定义谁是sender谁是receiver,但与此同时,如何:

def other_user(one_user)
  user_messages.reject do |msg|
    msg.user_id == one_user.id
  end.first.user
end

它需要user_messages的集合,过滤掉属于one_user的那个。数组中应该有一个,所以选择它并返回附加到它的用户。

修改

我可能无法理解您的所有要求,但我可能只是将sender_idreceiver_id直接添加到Message并删除UserMessage联接表。然后你可以定义如下的关系:

class User
  has_many :sent_messages, :class_name => 'Message', :foreign_key => 'sender_id'
  has_many :received_messages, :class_name => 'Message', :foreign_key => 'receiver_id'
end

class Message
  belongs_to :sender, :class_name => 'User'
  belongs_to :recipient, :class_name => 'User'
end

编辑2

如果您希望中间表用于跟踪特定于用户的状态,您可以考虑使用STI将UserMessage子类化为SentMessageLinkReceivedMessageLink(这些名称不是很棒 - 但是你明白了,然后就可以使用has_many :through

class SentMessageLink < UserMessage
  belongs_to :sender, :class_name => 'User'
  belongs_to :message
end

class User
  has_many :sent_message_links
  has_many :sent_messages, :through => :sent_message_links
end

class Message
  has_one :sent_message_link
  has_one :sender, :through => :sent_message_link
end

与收到的消息的类似代码。然后,您应该可以直接从邮件中访问senderreceiver

答案 1 :(得分:1)

这可以作为关联增强来实现。这对于大量消息是有效的,因为它将处理推送到DB。

class User < ActiveRecord::Base

    has_many :sent_messages, :class_name => "Message", :foreign_key => "sender_id"
    has_many :receivers, :through => :sent_messages, :source => :receiver do 
        def for_message(message_id)
            where("messages.id = ?", message_id)
        end
    end

    # Another association mapping for received_messages

end


class Message < ActiveRecord::Base

    belongs_to :sender, :class_name => "User", :foreign_key => "sender_id"
    belongs_to :receiver, :class_name => "User", :foreign_key => "receiver_id"

end


#Usage
User.first.sent_messages

#all users received messages from first user
User.first.receivers

#all users received messages from first user for message of message_id
User.first.receivers.for_message(message_id)