在我的Ruby on Rails应用程序中,我正在创建一个影院系统,在预订/新页面上,我允许用户通过下拉菜单选择所需的座位数量。但我想要做的是显示屏幕上当前空闲的座位数,例如,如果一个屏幕有50个座位而且已经预订了7个我希望系统显示:"有43个座位可用。 "我知道我需要一个方法,但我不确定如何实现它以及如何显示此消息。
值得注意的是,一个座位只能预订一个,因此对其他人来说是免费的,这意味着该方法必须能够计算可用于该节目的座位数量。
有人可以帮忙。
预订/ 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
表包含属性row_letter
和row_number
,但用户并未预订特定座位,只需要预订座位数量。
答案 0 :(得分:1)
在Screen
课程中添加:
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
答案 1 :(得分:0)
您需要确定两个值:特定演出的总座位数以及已预订的座位数。假设您有两个名为scr_id
和shw_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
变量
答案 2 :(得分:0)
修改强>
这样做的手动方式如下:
class Showing < ActiveRecord::Base
def booked_seats
bookings.pluck(:seats_quantity).sum
end
def available_seats
seats.count - booked_seats
end
end
<强> OLD 强>
这看起来很好用于Rails'counter_cache
。
class Booking < ActiveRecord::Base
belongs_to :showing, counter_cache: true
end
这会将计数存储在显示模型(您必须添加)的列中。然后,当您执行@showing.bookings.size
(不计数)时,它将引用该列。
“通过此声明,Rails将使缓存值保持最新,然后返回该值以响应size方法。” http://guides.rubyonrails.org/association_basics.html