我想在表中设置事件记录收集代理的排序顺序。
应按可用房间数量(从最高到最低)排序。
诀窍是 @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/