问题
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 => 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.
回答1:
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
回答2:
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
来源:https://stackoverflow.com/questions/6565078/dynamic-finder-methods-for-validation-purposes