Tôi đã có mô hình này mà đã làm việc tốt:validates_presence_of gây after_initialize được gọi với một tự lạ
class Weight < ActiveRecord::Base
belongs_to :user
validates_presence_of :weight, :measured_on
attr_accessible :weight, :measured_on
def after_initialize
self.measured_on ||= Date.today
end
end
tôi đã thêm nó dòng
validates_uniqueness_of :measured_on, :scope => :user_id
này và nó bắt đầu ném một lỗi trên xác thực. Không phải lỗi xác thực nhưng có lỗi của Ruby:
>> w.valid?
ActiveRecord::MissingAttributeError: missing attribute: measured_on
from /Users/pupeno/Projects/sano/app/models/weight.rb:8:in `after_initialize'
Tôi đã đặt một tuyên bố gỡ lỗi sau after_initialize và tôi đã nhận thấy điều gì đó không mong muốn. Khi tôi tạo một trọng lượng mới, nó hoạt động như mong đợi và đối tượng tự trên after_initialize là trọng lượng mong đợi:
>> w = Weight.new
/Users/pupeno/Projects/sano/app/models/weight.rb:9
self.measured_on ||= Date.today
(rdb:1) p self
#<Weight id: nil, user_id: nil, weight: nil, measured_on: nil, created_at: nil, updated_at: nil>
(rdb:1) c
=> #<Weight id: nil, user_id: nil, weight: nil, measured_on: "2009-11-22", created_at: nil, updated_at: nil>
Khi tôi chạy w.valid? nó trở nên kỳ lạ. after_initialize được gọi là một lần nữa, tôi không chắc chắn lý do tại sao, và tự đối tượng là gì tôi mong đợi:
>> w.valid?
/Users/pupeno/Projects/sano/app/models/weight.rb:9
self.measured_on ||= Date.today
(rdb:1) p self
#<Weight id: 1>
(rdb:1) p self.inspect
"#<Weight id: 1>"
(rdb:1) p self.class
Weight(id: integer, user_id: integer, weight: float, measured_on: date, created_at: datetime, updated_at: datetime)
(rdb:1) p self.measured_on
ActiveRecord::MissingAttributeError Exception: missing attribute: measured_on
(rdb:1)
Nó có vẻ như một đối tượng Trọng lượng được tạo ra mà không cần bất kỳ thuộc tính nhưng các thiết lập id. Bất kỳ ý tưởng tại sao? Đây có phải là lỗi hoặc hành vi dự kiến không? Tôi có làm điều gì đó sai bằng cách thiết lập các measur_on trên after_initialize?
workaround hiện tại của tôi, trong trường hợp bất cứ ai đang có cùng một vấn đề, là
class Weight < ActiveRecord::Base
belongs_to :user
validates_presence_of :weight, :measured_on
validates_uniqueness_of :measured_on, :scope => :user_id
attr_accessible :weight, :measured_on
def after_initialize
if self.has_attribute? :measured_on
self.measured_on ||= Date.today
end
end
end
nhưng tôi muốn có một giải pháp thích hợp.
OP đã chỉnh sửa phản hồi của tôi và tạo phần "has_attribute?: Measured_on" - Tôi không chắc chắn 100% rằng tôi đồng ý với nó sau khi xem nguồn đường ray - tôi nghi ngờ nó hoạt động do tác dụng phụ, thay vì - thiết kế). Tôi không quay trở lại phần đó của câu trả lời mặc dù, như những người hiểu biết, nó có thể giúp một ai đó. – oskarpearson
Tôi bị cắn vào ngày hôm nay. Bài đăng này và câu trả lời của bạn đã lưu thịt xông khói của tôi. Tôi đã quên rằng một trong những nhược điểm của ngôn ngữ động là bạn không phải lúc nào cũng có cùng thuộc tính trong một đối tượng ... có thể tốt nhưng cũng xấu :) –
Bị cắn bởi điều này ngày hôm nay. Wow, điều này đã được đăng ở đây trong năm 2009? Tôi rất ấn tượng rằng nó đã không còn tồn tại quá lâu. – Trejkaz