指南中的示例以及关联模型中的附加属性
class CreateAppointments < ActiveRecord::Migration
def change
create_table :physicians do |t|
t.string :name
t.timestamps null: false
end
create_table :patients do |t|
t.string :name
t.timestamps null: false
end
create_table :appointments do |t|
t.belongs_to :physician, index: true
t.belongs_to :patient, index: true
t.datetime :appointment_date
t.timestamps null: false
end
end
end
模型约会有一个验证:
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
validates :appointment_date, presence: true
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, through: :appointments
end
当我向患者some_physician.patient << some_patient
添加患者时,我必须定义appointment_date
。如何正确地做到这一点?
答案 0 :(得分:3)
如何正确地做到这一点?
在我看来,您可以定义一个方法,并将该方法传递给before_save
回调。
class Appointment < ActiveRecord::Base
before_save :set_appointment_date
private
def set_appointment_date
self.appointment_date = Time.now
end
end
每次创建关系时,您都不需要明确设置appointment_date
。它会自动为您设置。
修改强>
如果您以后想要before_save
约会对象,update
也会触发,尽管这是一种非常罕见的情况。但它会更新appointment_date
。为此,您可以使用before_create
回调,在这种情况下,只会触摸appointment_date
一次。
答案 1 :(得分:2)
The reason you have to define it is because some_physician.patient << some_patient
creates an implicit appointment to link the two. An appointment is invalid if you leave appointment_date
blank.
If you don't want an appointment, define a new relationship between physicians
and patients
.
Otherwise it makes sense to do something like:
appointment = some_physician.appointments.create(patient: some_patient, appointment_date: Time.now)
答案 2 :(得分:2)
It is can be achieved without before_save
callback, Rails update timestamps
automatically. Just create a right migration file, assume you are use postgresql
as orm.
create_table :appointments do |t|
t.belongs_to :physician, index: true
t.belongs_to :patient, index: true
t.timestamps :appointment_date, default: 'now()'
t.timestamps null: false
end
Instead datetime
columntype use timestamps
as created_at
or updated_at
with a plain sql function now()
Current date and time (equivalent to current_timestamp)
It's happens under the hood.