【问题标题】:How to get the first two records by simply ruby code(not using queries)如何通过简单的 ruby​​ 代码获取前两条记录(不使用查询)
【发布时间】:2019-01-20 22:55:12
【问题描述】:

我的主题模型是

class Topic < ActiveRecord::Base
  has_many :posts
  accepts_nested_attributes_for :posts
  validates_presence_of :topic
  validates :topic, length: { minimum: 3 }
end

我的帖子模型是

class Post < ActiveRecord::Base
  belongs_to :topic, counter_cache: true
  validates_length_of :title ,:minimum => 3
  validates_length_of :description,:minimum => 5
end

我的主题控制器是

class TopicsController < ApplicationController
  before_action :set_topic, only: [:show, :edit, :destroy, :update]
  def index
    @topics = Topic.all
  end
end

我的主题索引是

<h1>Topics</h1>
<table class="table">
  <% @topics.each do |t| %>
    <%= link_to t.topic,topic_posts_path(topic_id: t.id) %><%= "(# . 
t.posts_count})" %><br>
    <% @post= t.posts.limit(2) %>
    <% @post.each do |p| %>
      <li>
        <%=link_to p.title,topic_post_path(topic_id: p.topic_id,id: p.id) %><br>
      </li>
    <% end %>
    <%= link_to "more..", topic_posts_path(t.id)%><br>
   <% end %><br>
  <%= link_to "Add Topic",new_topic_path %>
</table>

我想在主题索引中显示与该主题相关的前两个帖子。我为此使用了limit,但是我可以使用 ruby​​ 来执行此操作而不向 db 传递任何查询吗?

【问题讨论】:

  • group_by 在您的问题中的作用是什么?
  • @JagdeepSingh 我不想将查询传递给 db 。我想使用 ruby​​ 命令来获取前两条记录。那么我可以使用 group_by 吗?
  • 要显示零帖子的主题吗?
  • @JagdeepSingh 不,我想显示与每个主题相关的前两个帖子。但不使用任何查询,如 limit,last
  • 我知道您希望显示每个主题的前两个帖子。但是帖子为零的主题呢?应该显示它们吗?

标签: ruby-on-rails ruby


【解决方案1】:

创建新的关联,它只需要 2 条相关模型帖子的记录。

topic.rb

has_many :recent_posts, -> { limit(2) }, class_name: 'Post'

topics_controller.rb

class TopicsController < ApplicationController
  before_action :set_topic, only: [:show, :edit, :destroy, :update]
  def index
    @topics = Topic.includes(:recent_posts)
  end
end

在你看来

<h1>Topics</h1>
<table class="table">
  <% @topics.each do |t| %>
    <%= link_to t.topic,topic_posts_path(topic_id: t.id) %><%= "(# . 
t.posts_count})" %><br>
    <% t.recent_posts.each do |p| %>
      <li>
        <%=link_to p.title,topic_post_path(topic_id: p.topic_id,id: p.id) %><br>
      </li>
    <% end %>
    <%= link_to "more..", topic_posts_path(t.id)%><br>
   <% end %><br>
  <%= link_to "Add Topic",new_topic_path %>
</table>

【讨论】:

  • 我还要提一下,#all 可能是这种方法中最邪恶的。
  • @mudasobwa 是的,更新了我的答案。当我对我的回答进行传奇评论时,我感到很自豪:)
  • @mudasobwa 哦,好吧。我忘了匆忙:)
  • @mudasobwa 我不应该使用限制。我可以通过 ruby​​ group_by 来获得前两条记录吗
  • @NARENPUSPHARAJU 显然没有办法在不限制数量的情况下检索有限数量的任何东西。您可能会加载所有内容,但这是一种反模式,我拒绝展示该方法。
【解决方案2】:

但是我可以在不向 db 传递任何查询的情况下使用 ruby​​ 来做到这一点吗?

是的,你可以。 控制器

  def index
    @topics = Topic.includes(:posts)
  end

查看

<h1>Topics</h1>
<table class="table">
<% @topics.each do |t| %>
  <%= link_to t.topic,topic_posts_path(topic_id: t.id) %><%= "(# . 
t.posts_count})" %><br>
  <%@posts= t.posts%>
  <% @posts.each_with_index do |p, index| %>
    <%if index <= 1%>
      <li>
        <%=link_to p.title,topic_post_path(topic_id: p.topic_id,id: p.id) %><br>
      </li>
    <%end%>
  <%end%>
  <%= link_to "more..", topic_posts_path(t.id)%><br>
  <br>
<%= link_to "Add Topic",new_topic_path %>
</table>

【讨论】:

  • 没有明确的includes 如@Vishal 的正确答案所示,这将产生N+1
  • @mudasobwa 我误解了这个问题吗? can I do this using ruby without passing any query to db?
  • 您提供的代码在此处向 DB 传递了一个附加查询:@posts= t.postsTopic.all 默认不从数据库中加载关联。
  • @mudasobwa 这样在控制器中它应该是@topics = Topic.includes(:posts),但是就用户的问题而言,不使用数据库查询和使用简单的红宝石,我的回答不应该被否决。不过,我很欣赏以标准方式提供的答案。
  • 您的答案肯定应该被否决,因为它不会以任何方式减少数据库查询的数量。打开控制台并检查。再次:@posts = t.posts对数据库执行查询
【解决方案3】:

您可以使用@post.last(2),这是一种 ruby​​ 方法。

【讨论】:

  • 对不起,但最后一个.last(2) 将在内部触发limit 2,这是一个sql 查询。
猜你喜欢
  • 1970-01-01
  • 2012-03-12
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-27
相关资源
最近更新 更多