简体   繁体   中英

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.

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 :

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 .

The message at the end sums things up well:

Use include for instance methods and extend for class methods. Also, it is sometimes ok to use include to add both instance and class methods. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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