我的应用程序设置在观看视频时运行ajax。 ajax在下面调用User#动作。问题是,当它第一次运行时,它可以工作并添加{"时间戳" =>" 1"}但它永远不会更新为{" timestamp" = >" 1,1"}。有什么我想念的吗?我可以不更新hstore散列中的值吗?
# Increases User's workouts after video is watched
def increase_workouts
@user = current_user
if logged_in?
if @user.newworkouts[Time.now.strftime("%Y%m%d").to_sym] == nil
@user.newworkouts[Time.now.strftime("%Y%m%d").to_sym] = "0"
end
@user.newworkouts[Time.now.strftime("%Y%m%d").to_sym] += "," + "1"
@user.save
render(json: { message: "Workouts increased" }, status: :ok) and return
else
render(json: { message: "Workouts increased" }, status: :ok) and return
end
end
答案 0 :(得分:0)
我认为ActiveRecord并没有意识到你已经改变了newworkouts
。如果你这样做:
h = { }
h[:k] = 6
或者这个:
h = { :k => 11 }
h[:k] = 6
然后h
本身并未实际更改,其内容已更改,但h.object_id
与h[:k] = 6
之前的内容相同。 PostgreSQL array columns and ActiveRecord可能会发生类似的事情,因此遇到类似问题的hstore
也不会令人感到意外。
解决方案应与数组相同:
真的改变哈希。
w = @user.newworkouts.dup
# update `w` as needed...
@user.newworkouts = w # Replace the reference
@user.save
手动将其标记为脏。
# Update @user.newworkouts as you are now...
@user.newworkouts_will_change! # Mark it as dirty.
@user.save
我还建议在模型的某个方法中隐藏该登录信息,然后您可以在控制器中说出@user.add_workout_at(Time.now)
,而不必担心内部表示的丑陋细节。
您可能还希望从此列的hstore
切换到jsonb
,然后您可以使用数组作为值({"timestamp": [0,1]}
)而不是某种CSV-in-像你一样正在做的字符串。