开发者

Dynamic finder methods for validation purposes

I am using Ruby on Rails 3.0.7 and I would like to find some records at run time for validation purposes but passing\setting a value for that finder method. That is, in a my class I have the following:

class Group <  < ActiveRecord::Base
  validates :relation_id,
    :presence  => true,
    :inclusion => {
      :in => ... # Read below for more information about
    }
end

If I set :in to be

:in => User.find(1).group_ids

it works, but I would like to set "some-dynamic-things" for the finder method instead of the 1 value stated below in the example. That is, I would like to do something like the following in order to pass to the model a <test_value> in someway:

class Group <  < ActiveRecord::Base
  validates :relation_id,
    :presence  => true,
    :inclusion => {
      :in =&g开发者_如何学运维t; User.find(<test_value>).group_ids
    }
end

Is it possible? If so, how can I pass the value to the constant?

P.S.: Just to know, I am trying to make that in order to move some logic from the controller to the model.


I'm inferring that what you're trying to do is enforce something like "Only users who are members of a group can save it." If that's the case, you have behavior that should stay in the controller.

Your model doesn't have access to the current session, and adding this logic will prevent you from using your model for other things in the future. For example, you'd never be able to save a group from a batch or maintenance job that wasn't associated with a user.

If you really want to do this you could put a current_user class level variable in the User object and set it in a before_filter...

class ApplicationController
  before_fitler :set_current_user
  def set_current_user
    User.current_user = #however you get your user in your controllers
  end
end

class User
  @@current_user
end

class Group
  validates :user_in_group
  def user_in_group
    return true unless User.current_user #if we don't have a user set, skip validation
    User.current_user.group_ids.include? self.id
  end
end


It looks like you want something like a proc to be run for the validator for the :in attribute. I think you may be threading in dangerous territory when you rely on load order of models and playing with "dynamic constants".

Instead how about just building your own custom validator for this case?
It's not that hard, and you will have full control of what you need:
http://guides.rubyonrails.org/active_record_validations_callbacks.html#creating-custom-validation-methods

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜