计算与另一条记录关联的记录数量

Count the amount of records are associated to another record

在我的 Ruby on Rails 应用程序中,我正在创建一个影院系统,在 bookings/new 页面上,我允许用户通过下拉式菜单。但是我想做的是在屏幕上显示当前空闲的座位数,例如如果屏幕有 50 个座位并且已经预订了 7 个我希望系统显示:"There are 43 seats available." 我知道我需要一个方法,但我不确定我将如何实现它以及我将如何显示此消息。

值得注意的是,一个座位只会为一场演出预订,因此其他人可以免费使用,这意味着该方法必须能够计算该演出的可用座位数量。

有人可以帮忙吗。

bookings/form.html.erb:

<%= form_for @booking do |f| %>
    <%= f.hidden_field :user_id %>
    <%= f.hidden_field :showing_id %>

    <%= image_tag "thor_hammer.jpg",:size => "900x250" %>
    <h1>NEW BOOKING:</h1>
    <tr>
        <td width="350px">
            <br><%= f.label :seats_quantity, 'Please Select The Amount of Seats Required:' %>
        </td>
        <td width="300px">
            <br><%= f.select :seats_quantity, '1'..'10' %><br>
        </td>
        <td width="300px">
            <div class="actions">
                 <br><%= f.submit 'Book Showing' %>
            </div>
            <br><%= render "/error_messages", :message_header => "Cannot save: ", :target => @booking %> 
        </td>
    </tr>
<% end %>

Screen.rb:

class Screen < ActiveRecord::Base
   has_many :seats
   has_many :showings
   def screens_info
       "#{name}"
   end
end

Seat.rb:

class Seat < ActiveRecord::Base
    belongs_to :screen
end

Booking.rb:

class Booking < ActiveRecord::Base
    belongs_to :user
    belongs_to :showing
end

Showing.rb:

class Showing < ActiveRecord::Base
   belongs_to :film
   has_many :bookings
   belongs_to :screen
end

架构:

create_table "bookings", force: :cascade do |t|
    t.integer  "user_id"
    t.integer  "showing_id"
    t.integer  "seats_quantity"
end

create_table "screens", force: :cascade do |t|
   t.string   "name"
end

create_table "showings", force: :cascade do |t|
   t.date     "show_date"
   t.time     "show_time"
   t.integer  "film_id"
   t.integer  "screen_id"
end

create_table "seats", force: :cascade do |t|
   t.string   "row_letter"
   t.integer  "row_number"
   t.integer  "screen_id"
end

值得注意的是,虽然 seats table 包含属性 row_letterrow_number 用户没有预订特定的座位,只是座位的数量他们需要。

在你的 Screen class 添加:

has_many :bookings, through: :showings

然后你的代码变成这样:

def remaining_seats
  seats.count - bookings.sum(:seats_quantity)  # <-- edited when I realized there was a quantity in a booking
end

def screens_info
  "#{name} (#{remaining_seats}/#{seats.count} remaining)"
end

您需要计算出两个值:特定演出的总座位数以及其中已预订的座位数。假设您有两个名为 scr_idshw_id 的变量,其中第一个代表屏幕 ID,第二个代表显示 ID。

总席位:

total_seats = Seat.where(screen_id: scr_id).count

总预订量:

total_bookings = Booking.where(showing_id: shw_id).count

然后你只需要计算两者之间的差异。

available_seats = total_seats - total_bookings

编辑:具体实施

它应该作为屏幕模型中的一个方法来实现:

def available_seatings(shw_id)
    total_seats = Seat.where(screen_id: this.id).count
    total_bookings = Booking.where(showing_id: shw_id).count
    return total_seats - total_bookings
end

然后在控制器中

@available_seatings = screen.available_seatings(shw_id)

然后您可以在视图中使用 @available_seatings 变量

编辑

手动执行此操作的方式如下:

class Showing < ActiveRecord::Base
  def booked_seats
    bookings.pluck(:seats_quantity).sum
  end

  def available_seats
    seats.count - booked_seats
  end
end

Rails' counter_cache.

这看起来很好用
class Booking < ActiveRecord::Base
  belongs_to :showing, counter_cache: true
end

这会将计数存储在显示模型(您必须添加)的列中。然后当你做@showing.bookings.size(不算数)时,它会引用那一列。

"With this declaration, Rails will keep the cache value up to date, and then return that value in response to the size method." http://guides.rubyonrails.org/association_basics.html