modelで共通のメソッドが欲しくて、インスタンス化したくないのでクラスメソッドとして呼び出したいのですが、undefined method になってしまいます。
model/concerns/common_mehod.rb
module CommonMethod extend ActiveSupport::Concern def self.set_factors_of(str, num) result = [] unless str.blank? add_str = "_" + str.to_s else add_str = "" end num.times do |n| result << "factor#{n + 1}" + add_str end return result end end
model/item.rb
この中のインスタンスメソッドの中で呼び出しています
include CommonMethod def set_all_avgs @article ||= self.article props = [:total_pt] props << CommonMethod.set_factors_of("avg", @article.factors_num) ⬅️これ props.each do |prop| result = self.votes.average(prop) self.send(prop.to_s.gsub(/pt/, "avg="), result) end end
コンソール
irb(main):002:0> item.set_all_avgs Traceback (most recent call last): 2: from (irb):2 1: from app/models/item.rb:25:in `set_all_avgs' NoMethodError (undefined method `set_factors_of' for CommonMethod:Module)
インスタンスメソッドとして定義すればいけます。
module CommonMethod extend ActiveSupport::Concern def set_factors_of(str, num) ##変更 result = [] unless str.blank? add_str = "_" + str.to_s else add_str = "" end num.times do |n| result << "factor#{n + 1}" + add_str end return result end end def set_all_avgs @article ||= self.article props = [:total_pt] props << self.set_factors_of("avg", @article.factors_num) props.each do |prop| result = self.votes.average(prop) self.send(prop.to_s.gsub(/pt/, "avg="), result) end end
追記
名前のつけ方が間違っていたのか名前を変えたら動くようになりました。
以前はファイル名common_method
モジュール名 CommonMethod
include CommonMethod
でした。それを以下のようにしましたら動きました。名前のつけ方何かまずかったでしょうか?
module Common extend ActiveSupport::Concern def hello puts "hello, world!" end module ClassMethods def set_factors_of(str, num) result = [] unless str.blank? add_str = "_" + str.to_s else add_str = "" end num.times do |n| result << "factor#{n + 1}" + add_str end return result end end end
回答2件
あなたの回答
tips
プレビュー