这个rails怎么调用只从一个id获取一个对象?

时间:2012-04-09 00:09:47

标签: ruby-on-rails

我有一个User模型和一个UserMessage模型(用于在两个用户之间保存私人消息的模型)

在我看来,我有......

<% if @message_items.any? %>
    <ol class="messages">
        <%= render partial: 'message_item', collection: @message_items%>
    </ol>
    <%= will_paginate @message_items %>
<% end %>

我用...渲染。

<li id="<%= message_item.id %>">
    <span class="user">
        <%= link_to message_item.user.name, message_item.user %>
    </span>
    <span>
        <%= message_item.title %>
    </span>
    <span>
        <%= message_item.body %>
    </span>
</li>

对象UserMessage(来自message_item)如何能够呈现User对象?我对UserMessage的设计只有以下属性“id,user_id,from_id,title,body,created_at,updated_at”。

我想它来自user_id,并且rails以某种方式建立连接并且能够从user_id中找到User对象。那是对的吗?

但我真正想要的是来自from_id(发送消息的人)的用户。有没有办法检索?我知道做类似的事情.. message_item.user.from_id不起作用。

我能想到的唯一方法就是做

<%= User.find(id= message_item.from_id).name %> 

但是在我的视图中放置如此​​多的代码似乎并不合适。对不起,但我已被超级卡住。帮助将不胜感激。感谢

4 个答案:

答案 0 :(得分:3)

您需要以下型号

class User < ActiveRecord::Base
  has_many :received_user_messages, 
             :class_name => "UserMessage", :foreign_key => :receiver_id

  has_many :sent_user_messages, :class_name => "UserMessage", 
             :class_name => "UserMessage", :foreign_key => :sender_id
end

class UserMessage < ActiveRecord::Base

  # should have sender_id and receiver_id columns
  # make sure you index these columns

  belongs_to :sender, :class_name => "User"   
  belongs_to :receiver, :class_name => "User"

end

执行以下操作,列出用户已收到的消息:

current_user.received_messages(:include => :sender).each do |message|
  p "[#{message.sender.name}]: #{message.content}"
end

执行以下操作,列出用户已发送的消息:

current_user.sent_messages(:include => :receiver).each do |message|
  p "[#{message.receiver.name}]: #{message.content}"
end

答案 1 :(得分:1)

试试这个:

在UserMessage类中,创建两个名为senderrecipient的类方法,以执行所需的复杂查询。然后在您的视图中使用这些方法。

答案 2 :(得分:1)

首先,您需要设置关联。我猜一个用户有很多消息,一条消息属于一个用户。

添加到模型中:

应用程序/模型/ user.rb

has_many :user_messages

*应用/模型/ user_messages.rb *

belongs_to :user

您可能需要在user_messages表中添加一个名为user_id

的列

当您获取控制器中的消息时,告诉rails立即加载相关用户,因此rails不必在以后执行此操作:

@message_items = UserMessage.includes( :user ).all

现在您可以非常轻松地访问“拥有”消息的用户对象:

<%= message_item.user.name %>

如果您需要用户拥有的所有消息,现在也很容易:

@user = User.find( some_id )
@user.messages # this returns an array with all the message objects

答案 3 :(得分:1)

我认为您正在为模型中的belongs_to寻找foreign_key选项。所以你需要的是在UserMessage消息

中指定像sender / from from from_id这样的东西
belongs_to :sender, foreign_key: :from_id, class_name: "User"

然后在模板中,您只需在视图中调用此关系。

message_item.sender

它应该与message_item.user相同。

如需进一步参考,请访问documentation for associations

此外,我建议您不要在模板中调用.name方法,但在模型中指定to_s方法。 klump在他的回答中指出的好方法是使用.include方法来获得更好的性能。它将在加载UserMessage数据时加载用户数据,而不是在另一个查询中加载。

Article.find :all, :include => :revisions

代码来自另一个答案 - Rails ActiveRecord: Is a combined :include and :conditions query possible?