Ruby我的命令 + 单击显示 Rails 方法而不是 ruby 方法。是否可以在 rails 应用程序中命令 + 单击 Ruby 方法?

Rubymine command + click shows Rails methods but Not ruby methods. is it possible to command + click Ruby methods in a rails app?

所以我会有类似...

MyClassname.find_by_name("电子邮件")

如果我命令并单击 find_by_name 我的 ruby 我的告诉我“method_missing” 因为它不是 RAILS 方法,它是 [=25 中的方法=].那么是否可以配置我的 Ruby 我的导航到 rails 和 ruby 方法?

你的MyClassname::find_by_name是Rails方法,不是纯粹的Ruby方法。但是它是动态定义的

是的,确实缺少这种方法:) 这样就可以了

我认为值得更详细地提及这一点以使其更清楚

请查看 Ruby 文档中的示例:

https://ruby-doc.org/core/BasicObject.html#method-i-method_missing

class Roman
  def roman_to_int(str)
    # ...
  end

  def method_missing(symbol, *args)
    str = symbol.id2name
    begin
      roman_to_int(str)
    rescue
      super(symbol, *args)
    end
  end
end

r = Roman.new
r.iv      #=> 4
r.xxiii   #=> 23
r.mm      #=> 2000
r.foo     #=> NoMethodError

您可以在 class 中定义方法 method_missing,在那里捕获错误并做出您想要的

在 Rails 中,这些方法以元编程方式定义

请查看Rails来源:

https://github.com/rails/rails/blob/main/activerecord/lib/active_record/dynamic_matchers.rb

该模块实现了 method_missing 方法,如 Ruby docs

def method_missing(name, *arguments, &block)
  match = Method.match(self, name)

  if match && match.valid?
    match.define
    send(name, *arguments, &block)
  else
    super
  end
end

并动态定义方法

def define
  model.class_eval <<-CODE, __FILE__, __LINE__ + 1
    def self.#{name}(#{signature})
      #{body}
    end
  CODE
end

private

def body
  "#{finder}(#{attributes_hash})"
end


def signature
  attribute_names.map { |name| "_#{name}" }.join(", ")
end

所以可以使用find_by作为前缀,属性名作为后缀

MyClassname.find_by_id(3)

甚至你可以使用很少的参数找到记录

MyClassname.find_by_id_and_name(3, 'name')

和使用 classic find_by 一样,如果使用 bang

找不到记录,您可以抛出异常
MyClassname.find_by_id!(3)

但是 Ruby我的不是那么聪明,它不使用 Ruby 解释器来检查动态方法的存在,所以这就是为什么你只看到 method_missing

在我看来,在代码中使用 classic find_by 方法比使用元编程后缀

更透明和易于理解