2

嗨,我有一个要重构的代码

def gear_type
  @gear_type ||= self.class.gear_types.find{|gears| gears["id"]==source["gear_type_id"]}["text"] if source["gear_type_id"]
end

def brand
  @brand ||= self.class.brands.find{|node| node["id"]==source["brand_id"].to_s}["text"] if source['brand_id']
end

什么是最好的方法?使用评估或定义方法?我已经尝试过了,但是我还没有发现一些错误:

%w(gear_type brand).each do |meth|
  define_method(meth){
    instance_variable_get("@#{meth}") rescue
      instance_variable_set("@#{meth}", self.class.send(meth.pluralize).find{|node| node["id"]==source["#{meth}_id"]}["text"]) if source["#{meth}_id"]
  }
end
4

3 回答 3

4

我只是编写一个可以参数化的通用查找器方法:

def gear_type
  @gear_type ||= generic_finder :gear_types, "gear_type_id"
end

def brand
  @brand ||= generic_finder :brands, "brand_id"
end

def generic_finder(collection, primary_key)
  self.class.send(collection).each do |object|
    return object["text"] if object["id"] == source[primary_key]
  end if source[primary_key]
  nil
end
于 2013-01-04T23:00:05.740 回答
1

instance_variable_get("@#{meth}")如果未设置实例变量,则不会引发错误,它返回 nil。所以你必须做几乎和你一样的事情:

%w(gear_type brand).each do |meth|
  define_method(meth){
    instance_variable_get("@#{meth}") || instance_variable_set("@#{meth}", self.class.send(meth.pluralize).find{|node| node["id"]==source["#{meth}_id"]}["text"]) if source["#{meth}_id"]
  }
end

您还应该重构该行。它上面有很多东西

%w(gear_type brand).each do |meth|
  def source(meth)
    @source ||= source["#{meth}_id"]
  end

  def class_meths(meth)
    self.class.send(meth.pluralize)
  end

  def look_for(meth)
    class_meths(meth).find{|node| node["id"] == source(meth)}["text"]
  end

  define_method(meth) do
    value = instance_variable_get("@#{meth}")
    instance_variable_set("@#{meth}", look_for(meth)) if !value && source(meth)
  end
end

这是一个尝试。不确定它是否变得更好,但我认为它更容易阅读。

哦!我刚刚意识到这些方法可能不会在元数据的范围内?方法被调用。但是哦,好吧,我认为这仍然是一个很好的例子:)

于 2013-01-04T22:48:19.367 回答
-1

仅使用 eval 可能更清洁:

%w(gear_type brand).each do |meth|
  eval <<-RUBY
    def #{meth}
      @#{meth} ||= self.class.#{meth.plural}.find{|item| item["id"]==source["#{meth}_id"]}["text"] if source["#{meth}_id"]
    end
  RUBY
end
于 2013-01-04T22:48:42.567 回答