【问题标题】:Rails - bookings not saving to databaseRails - 预订未保存到数据库
【发布时间】:2016-11-18 12:59:57
【问题描述】:

我正在使用 Rails 构建一个活动网站。创建活动时,用户可以提供付费和免费活动。似乎booking_id 仅分配给付费活动而不是免费活动。我检查了我的控制台,这绝对是这种情况。这显然会导致问题,我不太确定如何解决。

这是我的代码:

bookings_controller.rb

class BookingsController < ApplicationController

before_action :authenticate_user!

def new
    # booking form
    # I need to find the event that we're making a booking on
    @event = Event.find(params[:event_id])
    # and because the event "has_many :bookings"
    @booking = @event.bookings.new
    # which person is booking the event?
    @booking.user = current_user
    @booking.quantity = @booking.quantity
    @total_amount = @booking_quantity.to_f * @event_price.to_f

end

def create
    # actually process the booking
    @event = Event.find(params[:event_id])
    @booking = @event.bookings.new(booking_params)
    @booking.user = current_user
    #@total_amount = @booking.quantity.to_f * @event.price.to_f

    Booking.transaction do
        @booking.save!
        @event.reload
        if @event.bookings.count > @event.number_of_spaces
        flash[:warning] = "Sorry, this event is fully booked."
        raise ActiveRecord::Rollback, "event is fully booked"
        end 
    end

    if @booking.save

        # CHARGE THE USER WHO'S BOOKED
        # #{} == puts a variable into a string
        Stripe::Charge.create(amount: @event.price_pennies, currency: "gbp",
            card: @booking.stripe_token, description: "Booking number #{@booking.id}")

        flash[:success] = "Your place on our event has been booked"
        redirect_to event_path(@event)
    else
        flash[:error] = "Payment unsuccessful"
        render "new"
    end

    if @event.is_free?

        @booking.save!
        flash[:success] = "Your place on our event has been booked"
        redirect_to event_path(@event)
    end
end

private

def booking_params
    params.require(:booking).permit(:stripe_token, :quantity)
end

end

events_controller.rb

 class EventsController < ApplicationController
before_action :find_event, only: [:show, :edit, :update, :destroy,]
# the before_actions will take care of finding the correct event for us
# this ties in with the private method below
before_action :authenticate_user!, except: [:index, :show]
# this ensures only users who are signed in can alter an event

def index
    if params[:category].blank?
        @events = Event.not_yet_happened.order("created_at DESC")
    else
        @category_id = Category.find_by(name: params[:category]).id
        @events = Event.not_yet_happened.where(category_id: @category_id).order("created_at DESC")
    end
    # The above code = If there's no category found then all the events are listed
    # If there is then it will show the EVENTS under each category only
end

def show
end

def new
    @event = current_user.events.build
    # this now builds out from a user once devise gem is added
    # after initially having an argument of Event.new
    # this assigns events to users
end

def create
    @event = current_user.events.build(event_params)
    # as above this now assigns events to users
    # rather than Event.new

    if @event.save
        redirect_to @event, notice: "Congratulations, you have successfully created a new event."
    else
        render 'new'
    end
end

def edit
    # edit form
    # @edit = Edit.find(params[:id])
    @event = current_user.events.find(params[:id])
end

def update
    if @event.update(event_params)
        redirect_to @event, notice: "Event was successfully updated!"
    else
        render 'edit'
    end
end

def destroy
    @event.destroy
    redirect_to root_path
end

private

def event_params
    params.require(:event).permit(:title, :location, :date, :time, :description, :number_of_spaces, :is_free, :price, :organised_by, :url, :image, :category_id)
    # category_id added at the end to ensure this is assigned to each new event created
end

def find_event
    @event = Event.find(params[:id])
end







end

预订表

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"
end

我已将@booking.save! 添加到免费事件的创建方法中,但没有更改。我还添加了事务代码块以避免超额预订,但这仅适用于付费活动。任何帮助,不胜感激。

【问题讨论】:

  • 您是否尝试注释掉“redirect_to event_path(@event)”行?
  • 我建议使用'pry' gem 来调试。您可以在保存之前和之后放置 binding.pry 以仔细检查您的参数是否存在,或者它是否已保存并在事务结束时回滚。
  • 您似乎正在尝试创建一个事件,而 foreign_key 预订 ID 没有存储在事件表中?我对吗?那么请分享您的事件控制器和表单代码。
  • 请将您的日志添加到问题中。请参阅log/development.log(或您所在的任何环境)
  • 一个建议,您的Booking.transaction 逻辑似乎可以并且应该移至模型验证。

标签: ruby-on-rails ruby ruby-on-rails-4 model-view-controller


【解决方案1】:

分析你的create动作方法,我发现了以下检查:

  • 检查添加新数量后活动是否会超出容量
  • 保存预订
    • 如果活动是免费的,我们就完成了
    • 否则我们尝试创建 Stripe::Charge

所以create 操作可能如下所示:

def create
  # actually process the booking
  @event = Event.find(params[:event_id])
  @booking = @event.bookings.new(booking_params)
  @booking.user = current_user
  #@total_amount = @booking.quantity.to_f * @event.price.to_f

  if ( @event.bookings.sum(&:quantity) + @booking.quantity ) > @event.number_of_spaces
    flash[:warning] = "Sorry, this event is fully booked."
    redirect_to event_path(@event)
  end

  if @booking.save
    if @event.is_free?
      flash[:success] = "Your place on our event has been booked"
      redirect_to event_path(@event)
    else
      begin
        Stripe::Charge.create(
          amount: @event.price_pennies,
          currency: "gbp",
          source: @booking.stripe_token,
          description: "Booking number #{@booking.id}"
        )

        flash[:success] = "Your place on our event has been booked"
        redirect_to event_path(@event)
      rescue => e
        @booking.destroy  # delete the entry we have just created
        flash[:error] = "Payment unsuccessful"
        render "new"
      end
    end
  end
end

当然,您需要充分重构代码以确保您的控制器不会变得

【讨论】:

  • 很抱歉这么久才回复,但我已经离开了。上述代码将如何为免费活动分配预订 ID?
  • 如果@booking.save,请查看条件。如果条件成功,则无论事件类型(免费/付费)如何,都会创建一个预订 ID。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-07
  • 2016-07-02
  • 2014-08-20
  • 2011-01-14
  • 1970-01-01
  • 2021-10-27
相关资源
最近更新 更多