Добавление к хеш-значению в приложении hstore для Rails

У меня есть настройка приложения для запуска ajax после просмотра видео. Ajax вызывает действие User # ниже. Проблема в том, что при первом запуске он работает и добавляет {"timestamp" => "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

person Doughtz    schedule 09.08.2016    source источник


Ответы (1)


Я думаю, ActiveRecord не понимает, что вы изменили newworkouts. Если вы сделаете это:

h = { }
h[:k] = 6

или это:

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

тогда сам h фактически не изменился, его содержимое изменилось, но h.object_id то же самое до h[:k] = 6, что и после. Аналогичные вещи могут происходить с столбцами массива PostgreSQL и 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
    

Я также рекомендовал бы похоронить этот логин в методе вашей модели, тогда вы могли бы просто сказать @user.add_workout_at(Time.now) в своем контроллере и не беспокоиться об уродливых деталях внутреннего представления.

Вы также можете переключиться с hstore на jsonb для этого столбца, тогда вы можете использовать массив в качестве значения ({"timestamp": [0,1]}), а не какой-то CSV-in-a-string, как вы сейчас делаете.

person mu is too short    schedule 09.08.2016