简体   繁体   English

从模型轨道调用模块功能

[英]Calling Module Function From Model Rails

I'm getting a method or variable not defined when trying to use an array defined in a function in a module. 在尝试使用模块中的函数中定义的数组时,我得到一个method or variable not definedmethod or variable not defined

Here are the files: 这是文件:

/lib/states.rb

module States
  def fifty_states
    [
        'AL',
        'AK',
        'AZ',
        'AR',
        'CA',
        'CO',
        'CT',
        'DE',
        'FL',
        'GA',
        'HI',
        'ID',
        'IL',
        'IN',
        'IA',
        'KS',
        'KY',
        'LA',
        'ME',
        'MD',
        'MA',
        'MI',
        'MN',
        'MS',
        'MO',
        'MT',
        'NE',
        'NV',
        'NH',
        'NJ',
        'NM',
        'NY',
        'NC',
        'ND',
        'OH',
        'OK',
        'OR',
        'PA',
        'RI',
        'SC',
        'SD',
        'TN',
        'TX',
        'UT',
        'VT',
        'VA',
        'WA',
        'WV',
        'WI',
        'WY'
    ]
  end
end

/app/controller/player_to_team_histories_controller.rb

class PlayerToTeamHistory < ActiveRecord::Base
include States

def self.distinct_states
  joins(:player).select("DISTINCT players.HometownState").where("players.HometownState IN (?)", fifty_states)
end

If I open a console I can do this just fine: 如果我打开一个控制台,我可以做到这一点:

>> include States
Object

>> fifty_states
["AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY"]

I think you're confusing class with instance here. 我认为你在这里混淆了课堂。 If you want to call fifty_states from inside a class method (ie self.distinct_states ), then you'll have to use extend , not include : 如果你想从方法(即self.distinct_states )中调用fifty_states ,那么你将不得不使用extend ,而不是include

module A
  def foo
    "myfoo"
  end
end

class B
  extend A

  def self.bar
    foo
  end
end

B.bar
#=> "myfoo"

Note however that you then cannot call the method from an instance: 但请注意,您无法从实例调用该方法:

b = B.new
b.bar
#=> NoMethodError: undefined method `bar' for #<B:0x007fefc4e19db0>

Here's an article with more discussion on include vs extend . 是一篇关于include vs extend更多讨论的文章

The message at the end sums things up well: 最后的信息总结得很好:

Use include for instance methods and extend for class methods. 使用include实例方法并扩展类方法。 Also, it is sometimes ok to use include to add both instance and class methods. 此外,有时可以使用include来添加实例和类方法。 Both are really handy and allow for a great amount of code reuse. 两者都非常方便,并允许大量的代码重用。 They also allow you to avoid deep inheritance, and instead just modularize code and include it where needed, which is much more the ruby way. 它们还允许您避免深度继承,而只是模块化代码并将其包含在需要的地方,这更像是红宝石的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM