[英]Rails Name Error - Undefined local variable or method `booking'
I'm building an Events app in Rails and I've hit the error above which relates to this method in my Model - 我在Rails中构建了一个事件应用,并且在模型中遇到了与该方法有关的上述错误-
def validate_availability
errors.add(:base, 'event is fully booked') if booking.count >= event.number_of_spaces
end
The purpose of the method is to avoid over-booking of an event whereby a specific number of spaces are available. 该方法的目的是避免事件的超额预定,从而可以使用特定数量的空格。 In my Controller I have the following code - 在我的控制器中,我有以下代码-
Controller#Create 控制器#创建
def create
@event = Event.find(params[:event_id])
@booking = @event.bookings.new(booking_params)
@booking.user = current_user
if
@booking.set_booking
flash[:success] = "Your place on our event has been booked"
redirect_to event_booking_path(@event, @booking)
else
flash[:error] = "Booking unsuccessful"
render "new"
end
if @event.is_free?
@booking.save(booking_params)
end
if booking.count >= @event.number_of_spaces
flash[:error] = "Sorry, this event is now fully booked"
render "new"
end
end
I need to define booking.count in my controller but not sure what would work - tried a few things but nothings working. 我需要在控制器中定义booking.count,但不确定什么可以工作-尝试了几件事但没有任何效果。 I have the following in my schema - 我的架构中包含以下内容-
create_table "bookings", force: :cascade do |t|
t.integer "event_id"
t.integer "user_id"
t.string "stripe_token"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "quantity", default: 1
t.integer "total_amount"
t.string "stripe_charge_id"
t.string "booking_number"
end
The booking.count would rely upon the quantity of spaces/bookings a user wishes to make versus the number of spaces remaining but how do I express this? booking.count将取决于用户希望制作的空间/预订量与剩余空间的数量,但是我该如何表达呢? Do I need a total_bookings column in my table or a separate method? 我是否需要表中的total_bookings列或单独的方法?
UPDATE - 更新-
Booking.rb Booking.rb
class Booking < ActiveRecord::Base
belongs_to :event
belongs_to :user
before_create :set_booking_number
validates :quantity, presence: true, numericality: { greater_than_or_equal_to: 0 }
validates :total_amount, presence: true, numericality: { greater_than_or_equal_to: 0 }
validate(:validate_booking)
validate(:validate_availability)
def set_booking_number
self.booking_number = "MAMA" + '- ' + SecureRandom.hex(4).upcase
end
def set_booking
if self.event.is_free?
self.total_amount = 0
save!
else
self.total_amount = event.price_pennies * self.quantity
begin
charge = Stripe::Charge.create(
amount: total_amount,
currency: "gbp",
source: stripe_token,
description: "Booking created for amount #{total_amount}")
self.stripe_charge_id = charge.id
save!
rescue Stripe::CardError => e
# if this fails stripe_charge_id will be null, but in case of update we just set it to nil again
self.stripe_charge_id = nil
# we check in validatition if nil
end
end
end
def validate_booking
# stripe_charge_id must be set for not free events
unless self.event.is_free?
return !self.stripe_charge_id.nil?
end
end
private
def validate_availability
errors.add(:base, 'event is fully booked') if event.bookings.count >= event.number_of_spaces
end
end
For the counts of booking table, you should have a booking_count field in events table. 对于预订表的计数,您应该在事件表中有一个booking_count字段。 Use the counter cache for this. 为此使用计数器缓存。 For more details check http://guides.rubyonrails.org/association_basics.html
. 有关更多详细信息,请访问http://guides.rubyonrails.org/association_basics.html
。 This is very helpful when records are large. 当记录很大时,这非常有用。
Your migration for adding column should be similar as below: 您要添加列的迁移应类似于以下内容:
def change
add_column :events, :bookings_count, :integer, default: 0
Event.reset_column_information
Event.all.each do |e|
Event.update_counters e.id, :bookings_count => e.bookings.length
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.