问题 - 记录多次保存

时间:2016-08-22 15:17:12

标签: ruby-on-rails ruby

我遇到了创建操作的问题。传递验证时,记录将在数据库中保存两次。有时会有更多重复的记录。

IndividualTrainingController

  def create
    @individual_training = IndividualTraining.new(individual_training_params)
    Stripe.api_key = ENV['STRIPE_SECRET_KEY']
    token = params[:stripeToken]
    if @individual_training.valid?
      begin
        charge = Stripe::Charge.create(
          amount: (@individual_training.training_cost.cost * 100).floor,
          currency: 'pln',
          card: token
        )

        if charge && @individual_training.save
          redirect_to show_backend_individual_trainings_path(@client), notice: 'Pomyślnie dodano.'
        else
          render :new
        end
      rescue Stripe::CardError => e
        flash[:danger] = e.message
        render :new
      end
    else
      render :new
    end
  end

结果: enter image description here

你知道这种情况的原因是什么吗?如果您想了解更多信息,请写下评论。

更新: Individual_training模型:

class IndividualTraining < ActiveRecord::Base
  # **ASSOCIATIONS**********#
  belongs_to :trainer, class_name: 'Person', foreign_key: 'trainer_id'
  belongs_to :client, class_name: 'Person', foreign_key: 'client_id'
  belongs_to :training_cost
  # ************************#
  # **VALIDATIONS***************************#
  validate :set_end_on, if: :should_validate_end_on?
  validates_presence_of :start_on, :date_of_training,
                        :training_cost_id

  validates_presence_of :end_on if :set_end_on
  validate :date_and_start_on_validation
  validate :date_of_training_validation, if: :should_validate_date_of_training?
  validate :client_free_time_validation
  validate :trainer_free_time_validation
  # ****************************************#
  attr_accessor :credit_card, :card_code
  include PgSearch
  pg_search_scope :search, against: [:date_of_training, :end_on, :start_on],
                           associated_against:
                           { trainer: [:first_name, :last_name],
                             client: [:first_name, :last_name],
                             training_cost: [:duration, :cost] },
                           using: {
                             tsearch: { prefix: true }
                           }

  attr_accessor :duration, :day

  private

  def should_validate_date_of_training?
   !date_of_training.nil? && !end_on.nil?
  end

  def should_validate_end_on?
    !start_on.nil? && !training_cost_id.nil?
  end

  def date_and_start_on_validation
    unless start_on.blank?
      if date_of_training < Date.today
        errors.add(:base, 'Nie możesz ustalać terminu treningu wcześniej niż dzień dzisiejszy.')
      elsif date_of_training == Date.today
        if start_on <= Time.now
          errors.add(:base, 'Godzina dzisiejszego treningu jest wcześniejsza niż obecny czas.')
        end
      end
    end
  end

  # check if trainer work while will be individual_training
  def date_of_training_validation
    unless start_on.blank?
      trainer.work_schedules.each_with_index do |ti, ind|
        if ti.day_of_week == BackendController.helpers.translate_date(date_of_training)
          if (start_on.strftime('%H:%M')..end_on.strftime('%H:%M'))
             .overlaps?(ti.start_time.strftime('%H:%M')..ti.end_time.strftime('%H:%M'))
            break
          else
            errors.add(:base, 'Trening jest poza grafikiem pracy trenera.')
            break
          end
        elsif ind == trainer.work_schedules.size - 1
          errors.add(:base, 'Trener w tym dniu nie pracuje.')
        end
      end
    end
  end

  # check if client doesn't have another training or activity
  def client_free_time_validation
    unless start_on.blank?
      client.individual_trainings_as_client.where(date_of_training: date_of_training)
            .where('id != ?', id).each do |ci|
        if (start_on...end_on).overlaps?(ci.start_on...ci.end_on)
          errors.add(:base, 'Masz w tym czasie inny trening.')
        end
      end
      client.activities.where(day_of_week: BackendController.helpers.translate_date(date_of_training))
            .each do |ca|
        if (start_on...end_on).overlaps?(ca.start_on...end_on)
          errors.add(:base, 'Masz w tym czasie zajęcie grupowe.')
        end
      end
    end
  end

  def trainer_free_time_validation
    unless start_on.blank?
      trainer.individual_trainings_as_trainer.where(date_of_training: date_of_training)
             .where('id != ?', id).each do |ti|
        if (start_on...end_on).overlaps?(ti.start_on...ti.end_on)
          errors.add(:base, 'Trener ma w tym czasie inny trening.')
        end
      end

      trainer.activities.where(day_of_week: BackendController.helpers.translate_date(date_of_training))
             .where(person_id: trainer_id).each do |ta|
        if (start_on...end_on).overlaps?(ta.start_on...ta.end_on)
          errors.add(:base, 'Trener ma w tym czasie inne zajęcia.')
        end
      end
    end
  end

  def set_end_on
    unless training_cost_id.blank?
      training = TrainingCost.where(id: training_cost_id).first
      self.end_on = start_on + training.duration.minutes
    end
  end

  def self.text_search(query, querydate)
    if query.present? && querydate.blank?
      search(query)
    elsif query.present? && querydate.present?
      search(query + ' ' + querydate)
    elsif query.blank? && querydate.present?
      search(querydate)
    else
      all
    end
  end
end

创建操作后的日志(现在我有3个重复的记录):

17:44:09 web.1  | Started POST "/backend/people/2/trainers/98/individual_trainings" for 127.0.0.1 at 2016-08-22 17:43:59 +0200
17:44:09 web.1  | Processing by Backend::IndividualTrainingsController#create as HTML
17:44:09 web.1  |   Parameters: {"utf8"=>"✓", "authenticity_token"=>"tajWUcA+eYd9zdmqVkI/sGBqAYOC6GDVvmotFyjtLSB5nL+XUQr4CKBwrL0e1lUhg0q6tA146a31ni1VrrYtPw==", "individual_training"=>{"credit_card"=>"4242424242424242", "card_code"=>"123", "date_of_training"=>"2016-08-26", "start_on"=>"13:00", "training_cost_id"=>"1", "trainer_id"=>"98", "client_id"=>"2"}, "stripeToken"=>"tok_18lKaeEGh48V76DKtVTOD1ln", "id"=>"2", "trainer_id"=>"98"}
17:44:09 web.1  |   Person Load (0.2ms)  SELECT  "people".* FROM "people" WHERE "people"."id" = $1  ORDER BY "people"."id" ASC LIMIT 1  [["id", 2]]
17:44:09 web.1  |   Trainer Load (0.1ms)  SELECT  "people".* FROM "people" WHERE "people"."type" IN ('Trainer') AND "people"."id" = $1 LIMIT 1  [["id", 98]]
17:44:09 web.1  |   Client Load (0.1ms)  SELECT  "people".* FROM "people" WHERE "people"."type" IN ('Client') AND "people"."id" = $1 LIMIT 1  [["id", 2]]
17:44:09 web.1  |   TrainingCost Load (0.1ms)  SELECT  "training_costs".* FROM "training_costs" WHERE "training_costs"."id" = $1  ORDER BY "training_costs"."id" ASC LIMIT 1  [["id", 1]]
17:44:09 web.1  |   Person Load (0.1ms)  SELECT  "people".* FROM "people" WHERE "people"."id" = $1 LIMIT 1  [["id", 98]]
17:44:09 web.1  |   WorkSchedule Load (0.1ms)  SELECT "work_schedules".* FROM "work_schedules" WHERE "work_schedules"."person_id" = $1  [["person_id", 98]]
17:44:09 web.1  |   Person Load (0.1ms)  SELECT  "people".* FROM "people" WHERE "people"."id" = $1 LIMIT 1  [["id", 2]]
17:44:09 web.1  |   IndividualTraining Load (0.3ms)  SELECT "individual_trainings".* FROM "individual_trainings" WHERE "individual_trainings"."client_id" = $1 AND "individual_trainings"."date_of_training" = $2 AND (id != NULL)  [["client_id", 2], ["date_of_training", "2016-08-26"]]
17:44:09 web.1  |   Activity Load (0.3ms)  SELECT "activities".* FROM "activities" INNER JOIN "activities_people" ON "activities"."id" = "activities_people"."activity_id" WHERE "activities_people"."person_id" = $1 AND "activities"."day_of_week" = $2  [["person_id", 2], ["day_of_week", "Piątek"]]
17:44:09 web.1  |   IndividualTraining Load (0.1ms)  SELECT "individual_trainings".* FROM "individual_trainings" WHERE "individual_trainings"."trainer_id" = $1 AND "individual_trainings"."date_of_training" = $2 AND (id != NULL)  [["trainer_id", 98], ["date_of_training", "2016-08-26"]]
17:44:09 web.1  |   Activity Load (0.2ms)  SELECT "activities".* FROM "activities" INNER JOIN "activities_people" ON "activities"."id" = "activities_people"."activity_id" WHERE "activities_people"."person_id" = $1 AND "activities"."day_of_week" = $2 AND "activities"."person_id" = $3  [["person_id", 98], ["day_of_week", "Piątek"], ["person_id", 98]]
17:44:09 web.1  |   TrainingCost Load (0.2ms)  SELECT  "training_costs".* FROM "training_costs" WHERE "training_costs"."id" = $1 LIMIT 1  [["id", 1]]
17:44:09 web.1  |    (0.1ms)  BEGIN
17:44:09 web.1  |   CACHE (0.0ms)  SELECT  "training_costs".* FROM "training_costs" WHERE "training_costs"."id" = $1  ORDER BY "training_costs"."id" ASC LIMIT 1  [["id", 1]]
17:44:09 web.1  |   CACHE (0.0ms)  SELECT "individual_trainings".* FROM "individual_trainings" WHERE "individual_trainings"."client_id" = $1 AND "individual_trainings"."date_of_training" = $2 AND (id != NULL)  [["client_id", 2], ["date_of_training", Fri, 26 Aug 2016]]
17:44:09 web.1  |   CACHE (0.0ms)  SELECT "activities".* FROM "activities" INNER JOIN "activities_people" ON "activities"."id" = "activities_people"."activity_id" WHERE "activities_people"."person_id" = $1 AND "activities"."day_of_week" = $2  [["person_id", 2], ["day_of_week", "Piątek"]]
17:44:09 web.1  |   CACHE (0.0ms)  SELECT "individual_trainings".* FROM "individual_trainings" WHERE "individual_trainings"."trainer_id" = $1 AND "individual_trainings"."date_of_training" = $2 AND (id != NULL)  [["trainer_id", 98], ["date_of_training", Fri, 26 Aug 2016]]
17:44:09 web.1  |   CACHE (0.0ms)  SELECT "activities".* FROM "activities" INNER JOIN "activities_people" ON "activities"."id" = "activities_people"."activity_id" WHERE "activities_people"."person_id" = $1 AND "activities"."day_of_week" = $2 AND "activities"."person_id" = $3  [["person_id", 98], ["day_of_week", "Piątek"], ["person_id", 98]]
17:44:09 web.1  |   SQL (0.3ms)  INSERT INTO "individual_trainings" ("date_of_training", "start_on", "client_id", "trainer_id", "training_cost_id", "end_on") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"  [["date_of_training", "2016-08-26"], ["start_on", "2000-01-01 13:00:00.000000"], ["client_id", 2], ["trainer_id", 98], ["training_cost_id", 1], ["end_on", "2000-01-01 14:00:00.000000"]]
17:44:09 web.1  |    (11.1ms)  COMMIT
17:44:09 web.1  | Redirected to http://localhost:3000/backend/people/2/individual_trainings/show
17:44:09 web.1  | Completed 302 Found in 1250ms (ActiveRecord: 13.6ms)

1 个答案:

答案 0 :(得分:1)

我解决了我的问题,删除了重复的js脚本(在form.html.slim和application.js中本地)。