[英]Smart update on active record, choose fields to update
I have a problem that I do not know how to solve. 我有一个我不知道如何解决的问题。 I have a table targets, so the user creates a goal by setting the start date and end date of it automatically created days in my days table referring to that start and end date range.
我有一个表目标,因此用户可以通过在我的天数表中设置自动创建的天数的开始日期和结束日期来参考该开始日期和结束日期范围来创建目标。 But when I edit the goal I have a problem because its start and end date values are unique.
但是当我编辑目标时,我遇到了一个问题,因为它的开始和结束日期值是唯一的。 I would like to edit the date values if the user decided to change the start date to a more advanced date automatically the days that had already been created in the bank when he created the goal would be deleted if the user did not change the start date , but change the end date would be created in the bank only the dates forward of what had already been created before.
如果用户决定自动将开始日期更改为更高级的日期,我想编辑日期值,如果用户未更改目标日期,则在创建目标时已经在银行中创建的日期将被删除。开始日期,但是更改结束日期只能在银行之前创建的日期之前创建。
My code for Goal.rb and Day.rb is: 我的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: 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
Can anyone help? 有人可以帮忙吗?
It's not totally clear from your question what your overall goal is, but I'm going to infer: 从您的问题尚不清楚,您的总体目标是什么,但是我要推断:
Goal
s whose days don't overlap Goal
,它们的日子不要重叠 Goal
whose timespan contains it Goal
salesmen
salesmen
One thing that jumps out is that you're tracking the start and end date for each goal twice: once in goals.day_start
/ goals.day_end
, and again by creating a record in days
for each day. 跳出来的一件事是,您要跟踪每个目标的开始和结束日期两次:一次是在
goals.day_start
/ goals.day_end
, goals.day_end
一次是通过创建每天的days
记录。 You could then retrieve the start and end dates for a goal with something like this: 然后,您可以使用以下内容检索目标的开始日期和结束日期:
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")
Another problem is that Day
records are created only when you first create a Goal
record, and destroyed only when a Goal
is destroyed. 另一个问题是,仅当您首次创建
Goal
记录时才创建Day
记录,而仅在销毁Goal
时才将其销毁。 If you change the dates on a Goal
, you'll need to calculate the difference to figure out which days need to be added and deleted. 如果您更改了
Goal
的日期,则需要计算差额以找出需要添加和删除的日期。 Ruby's Set
class may be helpful here. Ruby的
Set
类在这里可能会有所帮助。 You might even want to consider putting that logic into a regular method, rather than a callback, and having a controller invoke it. 您甚至可能要考虑将该逻辑放入常规方法(而不是回调)中,并让控制器调用它。
One more thing to think about: it may not be strictly necessary to enforce uniqueness in the Day
model (and ActiveRecord doesn't actually guarantee uniqueness). 还有一件要考虑的事情:在
Day
模型中强制执行唯一性可能不是严格必要的(ActiveRecord实际上不能保证唯一性)。 You could also detect multiple Day
records with the same date and warn the user about the overlap, which may be preferable to throwing an error when the user tries to set an overlapping date. 您还可以检测到多个具有相同日期的
Day
记录,并向用户发出有关重叠的警告,这比在用户尝试设置重叠日期时抛出错误更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.