Подтвердить что ты не робот

Как вы заказываете пользовательский метод модели, который не имеет атрибута в SQL?

Ранее я заказал свои сообщения следующим образом:

@posts = Post.find(:all, :order => "created_at DESC")

Но теперь я хочу заменить created_at на собственный метод, который я написал в модели Post, который дает номер в качестве результата.

Мое предположение:

@posts = Post.find(:all, :order => "custom_method DESC")

, который терпит неудачу.

4b9b3361

Ответ 1

Он терпит неудачу, потому что вы просите свой db выполнить сортировку.

@posts = Post.all.sort {|a,b| a.custom_method <=> b.custom_method}

Обратите внимание, что это становится нетривиальным, если вы хотите запустить результаты поискового вызова и больше не хотите получать .all. Подумайте о своем дизайне немного, прежде чем идти с этим.

Ответ 2

Просто для продолжения ответа @Robbie

Post.all.sort_by {|post| post.custom_method }.reverse

Ответ 3

Как отмечалось в первом ответе, порядок - это команда Active Record, которая по сути делает SQL-запрос в вашей базе данных, но это поле фактически не существует в вашей базе данных.

Как кто-то еще прокомментировал, вы можете более чисто запустить метод Ruby sort_by, используя амперсанд (подробнее здесь):

Post.all.sort_by(&:custom_method)

Однако все усложняется в зависимости от того, что вы хотите сделать в своем представлении. Я поделюсь случаем, который недавно я сделал, в случае, если вы поможете решить свою проблему. Мне нужно было сгруппировать мой ресурс другим ресурсом под названием "категории", а затем отсортировать исходный ресурс с помощью "netvotes", который был методом пользовательской модели, а затем упорядочить по имени. Я сделал это:

  • Заказ по имени в контроллере: @resources = Resource.order(:name)
  • Группировка по категориям во внешнем цикле представления: <% @resources.group_by(&:category).each do |category, resources| %>
  • Затем сортировка ресурсов по голосам в частичном для ресурсов: <%= render resources.sort_by(&:netvotes).reverse %>

Вид немного запутан, так что вот полный цикл представления в index.html.erb:

<% @resources.group_by(&:category).each do |category, resources| %>
  <div class="well">
    <h3 class="brand-text"><%= category.name %></h3>
    <%= render resources.sort_by(&:netvotes).reverse %>
  </div>
<% end %>

И вот частица _resource.html.erb:

<div class="row resource">
  <div class="col-sm-2 text-center">
    <div class="vote-box">
      <%= link_to fa_icon('chevron-up lg'), upvote_resource_path(resource), method: :put %><br>
      <%= resource.netvotes %><br>
      <%= link_to fa_icon('chevron-down lg'), downvote_resource_path(resource), method: :put %>
    </div>
  </div>
  <div class="col-sm-10">
    <%= link_to resource.name, resource.link, target: "_blank" %>
    <p><%= resource.notes %></p>
  </div>
</div>

Ответ 4

Ну, просто Post.find(:all) вернет массив AR-объектов. Таким образом, вы можете использовать Array.sort_by и передать ему блок, и поскольку эти записи уже получены, вы можете получить доступ к виртуальному атрибуту внутри блока, который занимает sort_by.

RDoc: Enumerable.sort_by

Ответ 5

Это немного сложнее, чем то, что мне нравится, но это мне нравится держать мой вид, чтобы оставаться активной моделью записи, поэтому ее бит более сложный, чем просто

Post.all.sort_by {|post| post.custom_method }

что я делаю:

ids = Post.all.sort_by {|post| post.custom_method }.map(&:ids)
Post.for_ids_with_order(ids)

это настраиваемая область в модели Post

#app/models/post.rb
class Post < ApplicationRecord
  ...
    scope :for_ids_with_order, ->(ids) {
    order = sanitize_sql_array(
      ["position(id::text in ?)", ids.join(',')]
    )
    where(:id => ids).order(order)
  }

  ...
end

Я надеюсь, что эта помощь

Ответ 6

в рельсах 3 мы можем сделать это как: Post.order("custom_method DESC")
При обновлении приложения от rails2 до rails3