2016-08-22 35 views
0

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

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) 
+3

您确定这是后端问题吗?可能是您的前端客户端发送了两次请求?检查日志。 – MikDiet

+3

模型上的过滤器之前或之后是否有可能? – DMH

+0

你可以显示日志吗?也许多个请求正在同时发送? Stripe中创建了多少次收费? – AbM

回答

1

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

+1

这就是我的想法。当js与表单一起使用时,有时表单最终会被提交两次。 – Philip7899

+0

@ Philip7899您的评论建议我检查JavaScript脚本。谢谢! –