对活动记录进行智能更新,选择要更新的字段

时间:2017-10-30 20:10:35

标签: ruby-on-rails ruby rails-activerecord

我有一个问题,我不知道如何解决。我有一个表目标,因此用户通过在我的日期表中设置自动创建日期的开始日期和结束日期来创建目标,并指向该开始日期和结束日期范围。但是当我编辑目标时,我遇到了问题,因为它的开始和结束日期值是唯一的。我想编辑日期值,如果用户决定自动将开始日期更改为更高级的日期,那么如果用户没有更改,则在创建目标时已在银行中创建的日期将被删除开始日期,但更改结束日期将仅在银行中创建之前已创建的日期。

我的Goal.rb和Day.rb代码是:

class Goal < ApplicationRecord
  belongs_to :company
  has_many :days, dependent: :destroy
  has_many :goal_salesmen, dependent: :destroy
  has_many :salesmen, through: :goal_salesmen

  validates_presence_of :date_start, :date_end, :name, :totalvalue
  validates_uniqueness_of :date_start, :date_end, scope: :company_id
  validate :end_date_is_after_start_date

  after_create :create_days


  def create_days
    rangeDate = (self.date_start..self.date_end).to_a
    rangeDate.each do |date|
      self.days << Day.create(date_day: date, goal_id: self.id )
    end
  end

private

  def end_date_is_after_start_date
    if date_end < date_start
      errors.add(:date_end, "Data of end cannot be less than the data of start!")
    end
  end

end

Day.rb:

class Day < ApplicationRecord
  belongs_to :goal
  has_many :day_salesmen, dependent: :destroy
  has_many :salesmen, through: :day_salesman
  validates_presence_of :date_day, :goal_id
  validates_uniqueness_of :date_start, scope: :company_id

  accepts_nested_attributes_for :day_salesmen

end

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

从您的问题来看,您的总体目标并不完全清楚,但我要推断:

  • 您希望每家公司都有一组Goal天不重叠
  • 您希望每一天都与以下相关联:
    • 一个Goal,其时间跨度包含它
    • 0或更多salesmen

跳出来的一件事是,您需要两次跟踪每个目标的开始和结束日期:一次在goals.day_start / goals.day_end,再次在{{1}中创建记录每一天。然后,您可以使用以下内容检索目标的开始和结束日期:

days

另一个问题是Goal.where(id: YOUR_ID_HERE).joins(:days).group("days.id").select("goals.*, MIN(date_day) as date_start, MAX(date_day) AS date_end") 记录仅在您首次创建Day记录时创建,并且仅在Goal被销毁时销毁。如果您更改Goal上的日期,则需要计算差异以确定需要添加和删除的天数。 Ruby的Goal课程在这里可能会有所帮助。您甚至可能想要考虑将该逻辑放入常规方法而不是回调中,并让控制器调用它。

还有一件事需要考虑:在Set模型中强制执行唯一性可能并非绝对必要(而ActiveRecord实际上并不保证唯一性)。您还可以检测具有相同日期的多个Day记录,并警告用户重叠,这可能比用户尝试设置重叠日期时抛出错误更可取。