2015-08-02 14 views
6

Tôi có mô hình sự kiện. Mỗi sự kiện có thể có nhiều phiên.Rails xác nhận rằng mối quan hệ Có nhiều có ít nhất 1 mục nhập

Tôi muốn đảm bảo rằng không có mô hình nào có thể tồn tại mà không có mô hình có ít nhất 1 phiên được liên kết với nó.

validates :sessions, :length => { :minimum => 1 } 

Vấn đề là - khi tôi đi đến cố gắng tạo ra phiên trên một sự kiện đặc biệt bằng cách gọi phương pháp mô hình của tôi:

create_sessions() 

nào làm điều gì đó như:

sessions.create(event_id: id,date: x,day_of_the_week:x.strftime("%A"),classPin: pin) 

cho mỗi trong số ngày sự kiện sẽ chạy.

Nó không lưu với các lỗi:

ActiveRecord::RecordNotSaved in EventsController#create 
You cannot call create unless the parent is saved 

Tất nhiên - bởi thời điểm này kỷ lục sự kiện mới chưa được lưu - vì vậy sự liên kết này có thể chưa được tạo ra do tạo ra trên một hiệp hội không có sẵn cho đến khi cha mẹ được lưu! Vì vậy việc xác nhận hợp lệ giữa loại mối quan hệ này hoạt động như thế nào - vì xác thực xảy ra tại thời điểm tiết kiệm .... nhưng tôi muốn xác thực số lượng phiên sẽ lớn hơn 0 trước khi chúng tôi lưu sự kiện!

Trả lời

2

Tôi nghĩ cách đơn giản hơn là tạo sự kiện và phiên của bạn với new thay vì create nó sẽ chỉ tạo đối tượng nhưng không lưu trữ chúng vào cơ sở dữ liệu. Và sau khi bạn đã tạo các phiên của mình, hãy thực hiện một sự kiện của bạn theo số save.

@event = event.new(event_args) 
@event.sessions.new(session_args) 
@event.save 

Addition
Các @event.save sẽ lưu trữ các đối tượng @event và tất cả liên quan đến session đối tượng. Nếu không có thêm cấu hình chỉ mới các đối tượng sẽ được an toàn, xem Active Record Autosave Association để biết thêm thông tin.

+0

Xác thực phiên có xảy ra trong sự kiện lưu không? – RenegadeAndy

+1

Các phiên sẽ không được xác thực theo mặc định trên 'lưu', bạn sẽ cần phải thêm' validates_associated: sessions' xem [Hướng dẫn xác thực Rails] (http://guides.rubyonrails.org/active_record_validations.html#validates-associated). –

+0

Tính năng này có hoạt động không? Khi nào các phiên được lưu? – tompave

2

Điểm chính là xác thực của bạn xung đột với cách ActiveRecord hoạt động. Bạn đang tạo ra một nghịch lý.

Có một số giải pháp, nhưng bạn phải thư giãn xác thực. Đó là, nó không nên chạy khi hồ sơ là mới.

Bạn có thể định nghĩa nó như thế này:

class Event < ActiveRecord::Base 
    validates :sessions, length: { minimum: 1 }, 
         unless: :new_record? 
end 

Hoặc, để có sự linh hoạt hơn nữa, bạn có thể sử dụng một xác nhận tùy chỉnh:

class Event < ActiveRecord::Base 
    validate :session_count_validation 

    private 

    def session_count_validation 
    if !new_record? && sessions.count < 1 
     errors.add(:base, "Not enough sessions!") 
    end 
    end 
end 

phong cách thứ hai này cũng có lợi thế là hiệu suất cao hơn: sessions.count sẽ chỉ cần đếm số lượng bản ghi có sẵn Session liên quan, trong khi xác thực ban đầu của bạn sẽ tải tất cả chúng trong bộ nhớ và kiểm tra độ dài của mối quan hệ/arra y.

Sau đó, để đảm bảo rằng logic sáng tạo của bạn là âm thanh, bạn nên sử dụng một transaction:

begin 
    ActiveRecord::Base.transaction do 
    event = Event.create!(args) 

    sessions = dates.map do |date| 
     event.sessions.build(event_id: id, 
           date: date, 
        day_of_the_week: date.strftime("%A"), 
          classPin: pin) 
    end 

    sessions.each(&:save!) 
    end 
rescue 
    # your rescue logic 
    # e.g. display an error to the User 
end 

Vì vậy mà tất cả mọi thứ sẽ được triển khai một cách an toàn trở lại nếu bất kỳ hoạt động save! thất bại.

Các vấn đề liên quan