我有一个用户表,其中的列 total_user_xp
与 has_many :goals
关联。
“目标”表有一列 total_goal_xp
,它是通过以下方法在模型中计算的:
# goal.rb
belongs_to :user
has_many :goal_activities
has_many :activities, through: :goal_activities
def total_goal_xp
self.total_goal_xp = self.goal_activities.sum(:total_xp)
end
出于某种原因,在我的用户 Controller 和模型文件中,我无法计算 user_id 与 current_user 匹配的 total_goal_xp
总和。它始终返回值 0,就好像 Total_goal_xp 未存储在表中一样。
我对 Rails 还很陌生,但我感觉我的 total_goal_xp
方法没有将值保存到数据库中。每次调用该方法时似乎都会重新计算总和。也就是说,在 Rails 控制台中,运行 Goal.all 会为我提供一个具有正确值的表,因此我不明白为什么以下方法返回值 0。
用户 Controller .rb
def show
@user_goals = current_user.goals.all
@user_xp = @user_goals.sum(:total_goal_xp)
end
用户.rb
has_many :goals
def set_total_user_xp
goal = self.goals.all
self.total_user_xp = goal.sum(:total_goal_xp)
end
在服务器日志中,我得到以下 SQL - SELECT SUM("goals"."total_goal_xp") FROM "goals"WHERE "goals"."user_id"= ? [["user_id", 1]]
对于这两种方法。
我知道我不应该在 Controller 中进行计算,但目前,我只想让计算正常工作,这样我就知道关联正在工作。
如果您能就保存total_goal_xp
以及对total_user_xp执行相同操作的最佳实践提供任何建议,我们将不胜感激。
如果您想查看任何其他文件,请告诉我。
最佳答案
首先,您定义的方法名称与属性/列名称相同,这是冲突的。 其次,如果您想实时计算总数,则不需要这些列。
当列存在时,我可以解决此问题的一种方法是,使用此 answer
中提到的回调更改值时设置总值。
def set_total_xp
goal_activity = self.goal_activities.where(goal_id: goal_id).first_or_initialize
goal_activity.update_attribute(:total_xp, (quantity*goal.xp))
goal = Goal.find_by_id(goal_id)
user = goal.user
goal.update_attribute(:total_goal_xp, goal.goal_activities.sum(:total_xp))
user.update_attribute(:total_user_xp, user.goals.sum(:total_goal_xp))
end
或者您甚至不需要每次都重新计算总和
def set_total_xp
goal_activity = self.goal_activities.where(goal_id: goal_id).first_or_initialize
goal_activity.update_attribute(:total_xp, (quantity*goal.xp))
goal = Goal.find_by_id(goal_id)
xp = goal_activity.total_xp
goal.update_attribute(:total_goal_xp, (goal.total_goal_xp + xp))
goal.user.update_attribute(:total_user_xp, (user.total_user_xp + xp))
end
现在您不需要这些方法,而且在显示数据时,没有对数据库的查询命中..
关于mysql - Ruby on Rails - 总和计算不适用于模型中的关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44484979/