2

私のモデルのいくつかに次のコード行があります。

def average(scores)
  # get average of scores and round to two decimal places
  average = scores.inject{ |sum, el| sum + el }.to_f / scores.size
  average.round(2)
end

私はそれをさまざまなヘルパーファイルに入れようとしましたが、さまざまな成功を収めました-しかし、問題は、動作できないことではなく、含めるためだけにいくつかの醜いコードや追加のファイル (モジュールなど) が必要なことです。この方法はすべてのモデルで使用されていますが、これは危険信号です。それほど難しいことではないはずです。

ヘルパー コードは、コントローラーとビューにとっては簡単ですが、モデルにとっては直感に反するように思えます。同時に、まったく同じコードを 4 か所に (文字通り) 持つのはばかげているように思えます。これを乾かすのに最適な方法は何ですか?

アップデート

各モデルのメソッド内でヘルパーを使用したいaverage- すべてのケースで異なりますが、すべてが平均化される最後の行では、次のようになります。

def avg_for(student)
  scores = []
  self.evals.map do |student_id, evals|
    evals.select {student_id == student.id}.each do |eval|
      scores << eval.score
    end  
  end    
  average(scores) #here!
end
4

2 に答える 2

2

http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-average

class Student < ActiveRecord::Base
  has_many :evals

  def average_score
    evals.average(:score)
  end
end

レールの外側:

def average(score)
  (score.inject(:+).to_f / score.size).round(2)
end

編集

あなたのavg_for方法で:

def avg_for(student)
  evals.where(student: student).average(:score)
end
于 2013-09-12T14:16:32.253 に答える
1

この非常に具体的な方法については、@delba answer を使用できます。

モデル間でメソッドを共有することについてのあなたの質問に正確に答えるには、それは懸案事項です。

Rails-4 では、懸念事項が最上位の市民になり、ディレクトリapp/models/concernsとディレクトリapp/controllers/concernsが自動的に作成されます。

そのようなものを次のように追加できますapp/concerns/averageable.rb

module Averageable
  def average(scores)
    # get average of scores and round to two decimal places
    average = scores.inject{ |sum, el| sum + el }.to_f / scores.size
    average.round(2)
  end
end

次に、モデルで使用します。

class User < ActiveRecord::Base
  include Averageable
end

あなたの懸念からのメソッドは、それを含むどのモデルでも利用できます。

編集 :

rails-3 で同じことを行うには、懸念事項を入れたいパスを , に追加しconfig.autoload_pathsますconfig/application.rb

config.autoload_paths += %W(#{config.root}/lib/concerns)

averageable.rbモジュールをそのディレクトリに配置します。

于 2013-09-12T14:28:32.943 に答える