按特定属性类型链接到上一个/下一个记录

时间:2014-10-02 14:38:58

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

我有一个动物模型,目前由猫和狗组成。我有一个名为animal_type的列,它将定义动物是什么

当我查看记录(显示动作)时,它可能是任何动物类型,我创建了下一个和上一个链接以循环遍历所有动物记录:

def next_animal
 animal = self.class.order('created_at desc').where('created_at > ?', self.created_at)
 animal.first if animal
end

def previous_animal
 animal = self.class.order('created_at desc').where('created_at < ?', self.created_at)
 animal.last if animal
end

控制器

def show
 @animal = Animal.find(params[:id])
end

查看

<% if @animal.previous_animal %>
  <%= link_to(@animal.previous_animal, {class: 'prev-page'}) do %>
    <span class="glyphicon glyphicon-chevron-left"></span> Meet <span class="name"><%= @animal.previous_animal.name %></span>, the <%= animal_breed(@animal.previous_animal) %>
  <% end %>
<% end %>

所以,如果我正在看一只狗,我需要做什么来说只能循环通过下一只和以前的狗,而不包括任何猫,反之亦然,所以如果我在寻找在猫的记录中,只能绕过其他猫。

我已考虑过范围

scope :dog_type, -> { where(animal_type: 'Dog') }

但仍然不确定如何实施。

2 个答案:

答案 0 :(得分:1)

def next_animal
 animal = self.class.order('created_at desc').where('created_at > ? and animal_type = ?', created_at, animal_type)
 animal.first if animal
end

只需将其添加到where中,如果您使用范围,那么您将需要在上一个和下一个中使用if语句。

答案 1 :(得分:1)

您可以执行以下操作:

# model
def previous_animal
  self.class.order('created_at desc').where('created_at < ?', self.created_at).where(animal_type: self.animal_type).first
end

# view
<% if previous_animal = @animal.previous_animal %> # local assignment in the if condition
  <%= link_to(previous_animal, {class: 'prev-page'}) do %>
    <span class="glyphicon glyphicon-chevron-left"></span> Meet <span class="name"><%= previous_animal.name %></span>, the <%= animal_breed(previous_animal) %>
  <% end %>
<% end %>
  • 简化了previous_animal方法,在ActiveRecord :: Relation上调用.first无法失败,但可以返回nil
  • 我在if条件中使用了局部变量赋值,因为每次在记录上调用previous_animal时都会触发SQL查询。这种局部变量类似于缓存(不会多次触发SQL查询)。