ruby-on-rails - 表轨中 ActiveRecord::Associations::CollectionProxy 的排序顺序

标签 ruby-on-rails ruby sorting activerecord

我想在表中设置事件记录收集代理的排序顺序。 应按可用房间数量(从最高到最低)排序。 诀窍是 @rooms.reserved 是一个 bool 值,为了计算空闲/预订房间的数量,我必须使用辅助方法来避免记录收集代理错误。我得到了正确的结果,但我需要按可用房间的数量对表格进行排序。

我有两个模型:Room 和 Hotel。

class Room < ApplicationRecord
  belongs_to :hotel, optional: true # avoiding rails 5.2 belongs_to error 
  accepts_nested_attributes_for :hotel
end

class Hotel < ApplicationRecord
  has_many :rooms, dependent: :destroy
  accepts_nested_attributes_for :rooms
end

我有 table :

<table>
  <tr>
    <th>Name</th>
    <th>Rooms count</th>
    <th>Rooms status: in reserve || free</th>    
  </tr>

  <% @hotels.each do |hotel| %>
    <tr>
      <td><%= hotel.name %></td>
      <td><%= hotel.rooms_count %></td>
      <td><%= rooms_reservation_status(hotel.rooms) %></td>  <!-- rooms_reservation_status helper method in application_helper.rb -->      
      <td ><%= link_to 'Show', hotel_path(hotel) %></td>
      <td><%= link_to 'Destroy', hotel, method: :delete, data: { confirm: 'Are you sure?' } %>
    </tr>
  <% end %>
</table>

辅助方法

# rooms_reservation_status iterates throught ActiveRecord::Associations::CollectionProxy 
# and calculates the sum of free rooms aswell as a sum of reserved rooms
  def rooms_reservation_status(rooms)
    reserved = 0
    free     = 0
    rooms.each do |r|
      r.reserved == true ? reserved+=1 : free+=1
    end
    "#{reserved} || #{free}"
  end

房间的事件记录表:

class CreateRooms < ActiveRecord::Migration[5.1]
  def change
    create_table :rooms do |t|
      t.boolean :reserved, :default => false
      t.belongs_to :hotel, index: true

      t.timestamps
    end
  end
end

最佳答案

我会在 Room 模型上添加一个类方法,以便返回给定集合的空闲房间和预订房间的数量:

class Room < ApplicationRecord
  belongs_to :hotel, optional: true
  accepts_nested_attributes_for :hotel

  def self.reserved_count
    where(reserved: true).count
  end

  def self.free_count
    where(reserved: false).count
  end
end

一旦实现,您可以从 Hotel 模型中声明的关系调用它:

class Hotel < ApplicationRecord
  has_many :rooms, dependent: :destroy
  accepts_nested_attributes_for :rooms

  def reserved_rooms
    rooms.reserved_count
  end

  def free_rooms
    rooms.free_count
  end
end

您的 View 最终将如下所示:

<table>
  <tr>
    <th>Name</th>
    <th>Rooms count</th>
    <th>Rooms status: in reserved || free</th>    
  </tr>

  <% @hotels.each do |hotel| %>
    <tr>
      <td><%= hotel.name %></td>
      <td><%= hotel.rooms_count %></td>
      <td><%= "#{hotel.reserved_rooms} || #{hotel.free_rooms}" %></td>      
      <td ><%= link_to 'Show', hotel_path(hotel) %></td>
      <td><%= link_to 'Destroy', hotel, method: :delete, data: { confirm: 'Are you sure?' } %>
    </tr>
  <% end %>
</table>

对 Controller 中的酒店进行排序

在你的 Controller 中确保 eager load 酒店房间:

@hotels = Hotel.includes(:rooms).sort_by { |h| h.free_rooms.to_i }.reverse

您最终可以将其实现为 Hotel.includes(:rooms).sort_by(&:free_rooms).reverse

这样你就不需要任何加入或帮助。

关于您的评论,free_rooms 是作为实例方法实现的(例如 Hotel.first.free_rooms),因此它不可用于 ActiveRecord_Relation(例如Hotel.all.free_rooms)

关于ruby-on-rails - 表轨中 ActiveRecord::Associations::CollectionProxy 的排序顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46549519/

相关文章:

ruby-on-rails - Rake db:种子 rake 中止! ActiveRecord::RecordInvalid: 验证失败:电子邮件已经被占用

ruby-on-rails - 令人费解的 "duplicate key"错误 (PostgreSQL)

ruby-on-rails - 延迟作业超时

java - java中根据参数对对象进行排序

c - 使程序读取文件的某些部分

ruby-on-rails - 像偏执狂一样不恢复记录

ruby-on-rails - 不确定在哪里(模型或 Controller )定义我的查找方法

ruby-on-rails - Mongoid:搜索数组

ruby-on-rails - 为 ActiveAdmin Controller 设置过滤器 before_action

c# - 如何按每个对象的成员对对象列表进行排序?