DB に 2 つのテーブルがあります。users
とtrackers
。
ご想像のとおり、それぞれTracker
がテーブルにuser_id
関連していusers
ます。
このアプリのコンテキストは、チーム ベースのタイム トラッキング ソリューションの一部であるということです。その一環として、これまでに追跡した合計時間でユーザーを並べ替え、この合計を画面に表示する必要があります。
Tracker
そのため、 aが保存されるたびに、オブジェクトからとの値を取得するbefore_save
コールバックを起動し、トラッカーの時間を秒単位で簡単に取得できると考えました。結果は に保存されます。この部分が機能し、DB で計算値を確認できます。start_time
end_time
Tracker
(end_time - start_time).to_i
Tracker.tracked_time
ユーザーごとのすべてのTracker
インスタンスの値の合計結果を保存する必要があります。次に、この値をテーブルの列に保存して、データベースからこれを引き出して結果を並べ替えることができるようにします (考えてください: ほとんどアクティブなユーザー、最もアクティブでないユーザー、トップ 10)。tracked_time
users
tracked_time
ただし、これbefore_save :calculate_tracked_time, if: :finished?, unless: :admin?
を呼び出そうとすると、単にActiveRecord::RecordNotSaved
エラーが発生します。
User
モジュール内にいる間はモデルの値を保存できないようTracker
です…しかし、必要なことを行う理由や他の方法についての手がかりがありません。
これを機能させる(またはおそらくより良く機能させる)方法についての考えは大歓迎です。
あ:tracked_time
、User
型番は記載してありattr_accessible
ますので書いてあります。
以下はモデルです。必要に応じてモデルTracker
を投稿することもできUser
ます。
class Tracker < ActiveRecord::Base
attr_accessible :running, :start_time, :end_time, :tracked_time, :intention, :achievement
belongs_to :user
before_save :calculate_tracked_time, if: :finished?, unless: :admin?
validates :user_id, presence: true
validates :intention, presence: true,
length: { minimum: 5 }
default_scope order: 'trackers.created_at DESC'
private
def finished?
# Only save the total amount of time elapsed if we have
# a start_time AND end_time for this object.
!self.end_time.nil?
end
def admin?
# Don't calculate totals for the admin user.
User.find_by_id( self.user_id ).admin?
end
def calculate_tracked_time
# write the tracker's tracked time value in seconds
self.tracked_time = ( self.end_time - self.start_time ).to_i
# update the user's tracked time total
user = User.find_by_id( self.user_id )
# calculate time from all trackers this user has
total_time = 0
user.trackers.each { |t| total_time += t.tracked_time }
# this log correctly prints the correct figures.
p "Total Time for user (#{self.user_id}): #{total_time}"
# store it to the user's :tracked_time db column
user.tracked_time = total_time
# save !!! Errors out.
user.save
end
end
読んでくれてありがとう。