Часы работы рельсов - PullRequest
       11

Часы работы рельсов

0 голосов
/ 14 января 2019

У меня есть account model и open hours model. Я установил cocoon gem и при создании учетной записи я также добавляю часы работы. Все работает просто отлично, за исключением .... когда у меня один и тот же день, открывается и закрывается час на двух полях, вместо того, чтобы выдать ошибку проверки, он создает один и тот же объект два раза в БД. Любые идеи о том, как я могу проверить, если у меня есть тот же день и те же часы открывает и закрывает часы на другом поле?

class Account < ApplicationRecord
  has_many :open_hours
  accepts_nested_attributes_for :open_hours, reject_if: :all_blank, allow_destroy: true
end

class OpenHour < ApplicationRecord
  belongs_to :account

  validates_presence_of :day, :closes, :opens
  validates_inclusion_of :day, :in => 1..7
  validate :opens_before_closes
  validate :valid_from_before_valid_through

  validates_uniqueness_of :opens, scope: [:account_id, :day]
  validates_uniqueness_of :closes, scope: [:account_id, :day]

  protected
  def opens_before_closes
    errors.add(:closes, ". You have chosen the wrong hours or none at all!") if opens && closes && opens >= closes
  end

  def valid_from_before_valid_through
    errors.add(:valid_through, ". You have chosen the wrong hours or none at all!") if valid_from && valid_through && valid_from >= valid_through
  end
end

А это таблица открытых часов:

create_table "open_hours", force: :cascade do |t|
  t.integer "account_id"
  t.integer "day"
  t.time "opens"
  t.time "closes"
  t.datetime "valid_from"
  t.datetime "valid_through"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

Вот что публикуется при создании аккаунта:

    Started PATCH "/accounts/11" for 127.0.0.1 at 2019-01-14 21:18:22 +0200
Processing by AccountsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ENcVLQEa0y1Ppl+b2n1tSlCdzcVcY25p3hIPeipflxO3sUa1EbDc0Vnf+W5SS2TWamNE972LSP+ngDB2eEYRhg==",    
"account"=>{"name"=>"Sample 2", "street"=>"421 E DRACHMAN", "street_2"=>"", "city"=>"TUCSON", "state"=>"AZ", "postal_code"=>"85705-7598", 
"country"=>"USA", "phone"=>"3023694209", "web_address"=>"www.sample2.com", "category_id"=>["", "5", "10", "13"], "open_hours_attributes"=>{"0"=>{"day"=>"1",
"opens(1i)"=>"2000", "opens(2i)"=>"1", "opens(3i)"=>"1", "opens(4i)"=>"00", "opens(5i)"=>"00", "closes(1i)"=>"2000", "closes(2i)"=>"1", "closes(3i)"=>"1", 
"closes(4i)"=>"01", "closes(5i)"=>"00", "account_id"=>"#<Account:0x00007fd029cc1720>", "_destroy"=>"false", "id"=>"1"}, "1"=>{"day"=>"2", "opens(1i)"=>"2000", 
"opens(2i)"=>"1", "opens(3i)"=>"1", "opens(4i)"=>"00", "opens(5i)"=>"00", "closes(1i)"=>"2000", "closes(2i)"=>"1", "closes(3i)"=>"1", "closes(4i)"=>"01", 
"closes(5i)"=>"00", "account_id"=>"#<Account:0x00007fd029cc1720>", "_destroy"=>"false", "id"=>"2"}}}, "commit"=>"Update Account", "id"=>"11"}
  Account Load (0.4ms)  SELECT  "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT $2  [["id", 11], ["LIMIT", 1]]

Ответы [ 2 ]

0 голосов
/ 26 января 2019

Я бы просто предложил расширить использование ваших unless операторов, чтобы сделать их более читабельными, возможно, взломать сообщение об ошибке человека во 2-ю переменную

  def validate_uniqueness_of_in_memory(collection, attrs)

    hashes = collection.inject({}) do |hash, record|
      key = attrs.map {|a| record.send(a).to_s }.join
      key = record.object_id unless key.blank? || record.marked_for_destruction?
      hash[key] = record unless hash[key]
      hash  # can't recall if you actually need this as block returns whole self
    end

    msg = "Duplicate values in one or more fields"
    errors.add(:open_hours, msg) if collection.length > hashes.length
    end
  end
0 голосов
/ 15 января 2019

Единственное решение, которое я смог найти для этого, заключается в следующем. Если кто-то считает, что есть лучший способ реализовать это, пожалуйста, дайте мне знать.

Я поместил следующий код в account.rb

 def validate_unique_open_hours
   validate_uniqueness_of_in_memory(open_hours, [:day, :opens, :closes])
 end

  def validate_uniqueness_of_in_memory(collection, attrs)
    hashes = collection.inject({}) do |hash, record|
      key = attrs.map {|a| record.send(a).to_s }.join
      if key.blank? || record.marked_for_destruction?
        key = record.object_id
      end
      hash[key] = record unless hash[key]
      hash
    end
    if collection.length > hashes.length
      errors.add(:open_hours, "Duplicate values in one or more fields")
    end
  end
...