【问题标题】:Better way of looping over a SQL result set循环遍历 SQL 结果集的更好方法
【发布时间】:2013-09-01 22:17:15
【问题描述】:

我只是想知道是否有更好的方法来对存储在实例变量中的另一个 SQL 结果集执行 SQL 查询。

我的代码如下所示:

def index
  id = current_user.id.to_s

  #First SQL query
  @messages = Message.where("user_id = ? OR recipient_id = ?", id, id).group('recipient_id')
end

在我看来

<% @messages.each do |m| %>
<!-- Second SQL query -->
<% r = Tutor.find(m.recipient_id).user %>
  <%= "#{r.first_name + ' ' + r.last_name}" %><br />
  <%= m.subject %><br />
  <%= m.body %><br />
  <%= m.user_id %><br />
  <%= m.recipient_id %><br />
<% end %>

我正在循环@messages,然后对每个对象执行 SQL 查询,我想知道是否有更好(更智能)的方法来执行此操作? 谢谢!

【问题讨论】:

  • 我不认为你想要一个小组——你是说订单吗?
  • 不,组适合这种情况。谢谢!

标签: sql ruby-on-rails rails-activerecord


【解决方案1】:

您需要在 MessageTutor 之间建立 ActiveRecord 关联。我需要查看您的模型以准确说明如何将它们关联起来,但您基本上是在自己进行关联工作,而不是将其卸载到 AR/SQL。

一旦建立了适当的关系,您就会看到类似的情况。

在您的控制器中:

def index
  id = current_user.id
  @messages = Message.includes(:tutor).where("user_id = ? OR recipient_id = ?", id, id).group(:recipient_id)
end

在你看来:

<% @messages.each do |m| %>
  <%= m.tutor.user.to_s %><br />
  <%= m.subject %><br />
  <%= m.body %><br />
  <%= m.user_id %><br />
  <%= m.recipient_id %><br />
<% end %>

在您的用户模型中:

class User < ActiveRecord::Base
  def to_s
    "#{first_name} #{last_name}"
  end
end

【讨论】:

  • @DaniG2k 这个答案的要点是使用includes(:tutor)。这称为eager loading,并在加载关联记录时阻止 n+1 查询。
  • 顺便说一句,我认为"#{user.first_name} #{user.last_name}" 不应该在Tutor 中。最好将它放在Userfullname 方法中,然后执行m.tutor.user.fullname (IMO)。
  • 尽管他可能应该将 STI 用于UserTutor 之间的“关系”,而不是像他现在似乎正在做的 User belongs_to :tutorTutor :has_one :user。但这是另一个问题......
  • 感谢所有伟大的建议家伙!是的,理想情况下应该是 m.tutor.user.fullname。我的模型关系现在是这样设置的:class User &lt; ActiveRecord::Base has_one :tutor, dependent: :destroy has_many :messages endclass Tutor &lt; ActiveRecord::Base belongs_to :user has_many :messages, :foreign_key =&gt; 'recipient_id' endclass Message &lt; ActiveRecord::Base belongs_to :user belongs_to :tutor end 我怎样才能设置它以便我可以简单地做 m.tutor.user ?非常感谢!!!
  • 是的,我已经改变了我的模型,以便我现在可以做 m.tutor.user 并且它工作正常!谢谢:D
猜你喜欢
  • 1970-01-01
  • 2019-02-18
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 2015-06-08
  • 2013-09-14
  • 2018-08-09
相关资源
最近更新 更多