在hstore for Rails app中添加哈希值

时间:2016-08-09 20:23:04

标签: ruby-on-rails postgresql rails-activerecord hstore

我的应用程序设置在观看视频时运行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

1 个答案:

答案 0 :(得分:0)

我认为ActiveRecord并没有意识到你已经改变了newworkouts。如果你这样做:

h = { }
h[:k] = 6

或者这个:

h = { :k => 11 }
h[:k] = 6

然后h本身并未实际更改,其内容已更改,但h.object_idh[:k] = 6之前的内容相同。 PostgreSQL array columns and ActiveRecord可能会发生类似的事情,因此遇到类似问题的hstore也不会令人感到意外。

解决方案应与数组相同:

  1. 真的改变哈希。

    w = @user.newworkouts.dup
    # update `w` as needed...
    @user.newworkouts = w # Replace the reference
    @user.save
    
  2. 手动将其标记为脏。

    # Update @user.newworkouts as you are now...
    @user.newworkouts_will_change! # Mark it as dirty.
    @user.save
    
  3. 我还建议在模型的某个方法中隐藏该登录信息,然后您可以在控制器中说出@user.add_workout_at(Time.now),而不必担心内部表示的丑陋细节。

    您可能还希望从此列的hstore切换到jsonb,然后您可以使用数组作为值({"timestamp": [0,1]})而不是某种CSV-in-像你一样正在做的字符串。