0

如何使用 Model 和 controller not view 获取如下所示的记录?

模式1。有帮手

application_helper

def user_link(username)
    link_to User.find_by_username(username).user_profile.nickname, show_user_path(username)
end

看法

<% @topics.order("updated_at DESC").limit(100).each do |topic| %>
    <%= user_link(topic.comment_threads.order("id").last.user.username) if topic.comment_threads.present? %>
<% end %>

模式2。没有帮手。只看

<% @topics.order("updated_at DESC").limit(100).each do |topic| %>
    <%= link_to(topic.comment_threads.order("id").last.user.nickname, show_user_path(topic.comment_threads.order("id").last.user.username) ) if topic.comment_threads.present? %>
<% end %>

更新

  <%  @community.topics.eager.recent.each do |topic| %>
    <%= user_link(topic.comment_threads.order("id").last.user.username) if topic.comment_threads.present? %>
  <% end %>
4

1 回答 1

1

SQL 代码或 SQL 构建器永远不应该到达视图层。这应该在您的模型中。我什至不会在控制器中放置这样的查询。

我会将topicSQL 构建器提取到命名范围中。最重要的是,为了避免 n+1 查询,我将创建另一个命名范围eager

# topic.rb

scope :eager, includes(comment_threads: :user)
scope :recent, lambda { |n = 100| order("updated_at DESC").limit(n) }

然后我comment_threads会将 SQL 构建器移动到您的 comment_threads 模型中:

# comment_thread.rb

def self.last_user_nickname
  order("id").last.user.nickname
end

我们现在可以整理您的意见:

<% @topics.eager.recent.each do |topic| %>
  <%= user_link(topic.comment_threads.last_user_nickname) if topic.comment_threads.present? %>
<% end %>

请允许我把Slim卖给你(erb 替代品):

- @topics.eager.recent.each do |topic|
  = user_link(topic.comment_threads.last_user_nickname) if topic.comment_threads.present?

我什至可能更进一步,将其提取user_linkUserDecorator. 有关详细信息,请参阅https://github.com/drapergem/draper

概括

  1. 提取 SQL builder for topicintoeagerrecentscopes 下topic
  2. 提取 SQL builder for comment_threadsinto last_user_nicknameundercomment_thread
  3. 研究提取user_linkUserDecorator
  4. 使用苗条!:)
于 2013-01-20T21:59:34.927 回答