Eval альтернатива - PullRequest
       2

Eval альтернатива

0 голосов
/ 20 декабря 2011

В моем приложении есть bazillion контроллеров, и мне было интересно, как использовать метапрограммирование, чтобы облегчить обслуживание без головной боли.Это работает, но оно сопровождается опасностью в форме eval:

  def plural_action(method_name)
    class_name =  self.class.to_s.gsub( %r{^(\w*)Controller} ) {|s| $1 } 
    @title = "#{method_name.to_s.titlecase} of #{class_name}" 
    eval "@q = #{class_name.singularize}.where(:client_id => current_user.client_id).search(params[:q])"
    eval "@#{class_name.downcase} = @q.result(:distinct => true).paginate(:page => params[:page])"
    eval "session[:query] = @#{class_name.downcase}.map(&:id)"
    eval "respond_with(@#{class_name.downcase})" 
  end

Могу ли я сделать это без использования eval?Я возился с instance_variable_set, send и const_get, но пока не повезло.

Вот пример того, что я бы хотел, чтобы метод был оценен.

  def index
    @title = "Index of Books" 
    @q = Book.where(:client_id => current_user.client_id).search(params[:q])
    @books = @q.result(:distinct => true).paginate(:page => params[:page])
    session[:query] = @books.map(&:id)
    respond_with(@books)
  end

Ответы [ 2 ]

3 голосов
/ 20 декабря 2011

Существует великолепный метод constantize, который превращает строку в константу (примером которой являются типы классов), которую она представляет. Имея это в виду, я думаю, вы могли бы переписать свой метод как:

def plural_action(method_name)
    class_name =  self.class.to_s.gsub( %r{^(\w*)Controller} ) {|s| $1 } 
    @title = "#{method_name.to_s.titlecase} of #{class_name}" 
    @q = class_name.singularize.constantize.where(:client_id => current_user.client_id).search(params[:q])
    self.instance_variable_set("@#{class_name.downcase}", @q.result(:distinct => true).paginate(:page => params[:page]))
    session[:query] = self.instance_variable_get("@#{class_name.downcase}").map(&:id)
    respond_with(self.instance_variable_get("@#{class_name.downcase}"))
end
0 голосов
/ 20 декабря 2011
def plural_action(method_name)
    class_name =  self.class.to_s.gsub( %r{^(\w*)Controller} ) {|s| $1 } 
    @title = "#{method_name.to_s.titlecase} of #{class_name}" 
    @q = class_name.singularize.constantize.where(:client_id => current_user.client_id).search(params[:q])
    instance_variable_set class_name.downcase, @q.result(:distinct => true).paginate(:page => params[:page])
    session[:query] = @q_result.map(&:id)
    respond_with(@q_result)
end
...