2013-02-08 35 views
16

Tôi có hai mô hình liên quan - giả sử ActivityStep. Activity has_many :stepsStep belongs_to :activity có nghĩa là bảng cho steps có cột activity_id.Ngăn chặn thay đổi một trường trong mô hình Rails

Đây là trong Hobo 1.3, do đó, Rails 3.0.

Điều tôi muốn là đảm bảo rằng sau khi Step tạo không thể chuyển bước sang một số khác Activity. Chúng tôi không muốn trường activity_id thay đổi.

Tôi đã xóa trường khỏi biểu mẫu chỉnh sửa nhưng tôi đang tìm một ràng buộc mạnh hơn. Về cơ bản, tôi muốn xác thực trên update (không phải trên create) rằng cột không được chạm vào. Tài liệu của Hobo không gợi ý gì về việc sắp xếp bên trong Hobo, vì vậy tôi đang xem Rails validations, nhưng cho đến nay tôi chưa tìm thấy ràng buộc "chỉ làm điều này khi cập nhật" mà tôi nhớ, cũng không xác nhận thay đổi.

Trả lời

29

Bạn có thể khai báo thuộc tính là read_only với attr_readonly :your_field_name. Nhưng điều này sẽ không tạo ra lỗi nếu bạn cố gắng viết thuộc tính này, nó sẽ không âm thầm. (Thuộc tính này sẽ bị bỏ qua cho tất cả các SQL cập nhật)

tùy chọn khác có thể được, để viết một xác nhận cho trường hợp này, có thể trông như thế này:

class Step < ActiveRecord::Base 
    validate :activity_id_not_changed 

    private 

    def activity_id_not_changed 
    if activity_id_changed? && self.persisted? 
     errors.add(:activity_id, "Change of activity_id not allowed!") 
    end 
    end 
end 

persisted? trả về true, nếu đây không phải là một kỷ lục mới và nó không bị phá hủy.

Links:

http://api.rubyonrails.org/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html#method-i-readonly_attributes

http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-persisted-3F

+0

'attr_readonly' hoạt động như được quảng cáo, b ut có thể gây ra nếp nhăn với một khía cạnh khác của ứng dụng. Tôi sẽ thử phương pháp xác nhận vào ngày mai và xem điều đó có tốt hơn không. – pjmorse

+0

Nếu bạn thực sự cần thay đổi ID ở một nơi khác trong ứng dụng của mình, bạn có thể thực hiện điều này ngay cả với phương pháp xác thực như sau: 'step.save (: validate => false)' – Deradon

+0

Nó không phải là vấn đề thay đổi ở nơi khác; đó là một bản sao đối tượng. (Vì vậy, giả sử chúng ta đã sao chép một cách giả định 'Hoạt động' theo cách sao chép tất cả các bước '; vì một lý do nào đó không hiệu quả, và tôi chưa đào sâu đủ vào mã sao chép để hiểu nếu thay đổi này đã phá vỡ nó .) – pjmorse

1

Tôi nghĩ bạn có thể làm điều này quá với hệ thống quyền Hobo: http://hobocentral.net/manual/permissions

Ví dụ:

def update_permitted? 
    acting_user.administrator && !activity_id_changed? 
end 
Các vấn đề liên quan