从模型轨道调用模块功能

时间:2012-11-30 02:01:46

标签: ruby-on-rails model module

尝试使用模块中函数中定义的数组时,我得到method or variable not defined

以下是文件:

/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

如果我打开一个控制台,我可以做到这一点:

>> 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"]

1 个答案:

答案 0 :(得分:2)

我认为你在这里混淆了课堂。如果您想从方法(即fifty_states)内拨打self.distinct_states,那么您必须使用extend,而不是include

module A
  def foo
    "myfoo"
  end
end

class B
  extend A

  def self.bar
    foo
  end
end

B.bar
#=> "myfoo"

但请注意,您无法从实例调用该方法:

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

以下是an article,对include vs extend进行了更多讨论。

最后的信息总结得很好:

  

使用include for instance方法并扩展类方法。此外,有时可以使用include来添加实例和类方法。两者都非常方便,并允许大量的代码重用。它们还允许您避免深度继承,而只是模块化代码并将其包含在需要的地方,这更像是红宝石。