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

发布于 2024-11-17 08:33:43 字数 465 浏览 2 评论 0原文

消息有_许多用户_消息。它有两个。

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

Message has_many user_messages. It has two.

1 UserMessage will have the sender as user_id

The other UserMessage will have the receiver as user_id

Knowing one user, how can I, for any message, find the other?

Here's what I tried as a method to the Message class, but it fails:

 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

可爱暴击 2024-11-24 08:33:43

这可以作为关联增强来实现。这对于大量消息来说非常有效,因为它将处理推送到数据库。

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)

This could be implemented as an association enhancement. This will be efficient for high-volume of messages as it pushes processing to 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)
隱形的亼 2024-11-24 08:33:43

似乎应该更好地定义谁是发送者和谁是接收者,但与此同时,又如何:

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

EDIT 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

It seems like there should be a better definition of who is the sender and who is the receiver, but in the meantime, what about:

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

It takes the set of user_messages, filters out the one that belongs to one_user. There should be one left in the array, so pick it out and return the user attached to it.

EDIT

I might not understand all your requirements, but I'd probably just add a sender_id and receiver_id directly to Message and remove the UserMessage join table. Then you could define the relationship like:

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

EDIT 2

If you want the intermediate table for tracking user-specific states, you could look into using STI to subclass UserMessage as SentMessageLink and ReceivedMessageLink (those names are not awesome -- but you get the idea), then you could use 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

with similar code for received messages. Then you should be able to access sender and receiver right from the message.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文