Dynamic finder methods for validation purposes

泄露秘密 提交于 2020-02-25 03:20:27

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!