开发者

Rails validate association only when loaded

开发者 https://www.devze.com 2023-03-17 22:41 出处:网络
I have an activity model which has_many participants and I\'d like to ensure that a participant always exists when updating an activity and its participants. I have the following method in my activity

I have an activity model which has_many participants and I'd like to ensure that a participant always exists when updating an activity and its participants. I have the following method in my activity model which does the trick:

def must_have_participant
  if self.participants.size == 0 || self.participants.size == self.participants.to_ary.find_all{ |p| 开发者_JAVA技巧p.marked_for_destruction? }.count
    self.errors[:base] << I18n.t(:msg_activity_must_have_participant)
  end
end

The problem is that the participants are lazy loaded if I'm simply updating the activity on its own which I'd like to avoid. I've tried the following alternative, however, loaded? returns false when removing all participants using the :_destroy flag.

def must_have_participant
  if self.new_record? || self.participants.loaded?
    if self.participants.size == 0 || self.participants.size == self.participants.to_ary.find_all{ |p| p.marked_for_destruction? }.count
      self.errors[:base] << I18n.t(:msg_activity_must_have_participant)
    end
  end
end

Is there an alternative to loaded? that I can use to know whether the participants are going to be updated?


I did something like this in a recent validation that I created. I searched for the original record and checked the original value against the new value. No guarantees my code will work for you but here is my code for your application:

    orig_rec = self.find(id)
    if participant_ids.size != orig_rec.participant_ids.size

Note that I checked the size of participant_ids instead of fetching all the participant records and checking the size of them. That should be more efficient.

I don't know if there is some kind of built in function to do this or not in ruby, I'll be curious to see what someone who is more rails specific may suggest.


For reference I've amended the method like so:

def must_have_participant
  if self.new_record? || self.association(:participants).loaded?
    if self.participants.size == 0 || self.participants.size == self.participants.select{ |p| p.marked_for_destruction? }.size
      self.errors[:base] << I18n.t(:msg_must_have_participant)
    end
  end
end
0

精彩评论

暂无评论...
验证码 换一张
取 消