ActiveRecord не знает часовых поясов? - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть один вопрос относительно часового пояса

Я сделал следующее, моя активная запись все еще не совпадает с моим часовым поясом, когда я выполняю следующий запрос

def stock_by_date(date)
   UserStock.where("date(created_at) = ? and user_id = ? ", date , current_user.id)
end

Я сделалследуя в сторону my application.rb

config.active_record.default_timezone = :utc
config.active_record.time_zone_aware_attributes = true
config.beginning_of_week = :sunday
config.active_record.time_zone_aware_types = [:datetime, :time]

Я добавил поле часового пояса в свой метод регистрации, и он правильно отображает текущий день часового пояса, но когда я добавил акцию для часового пояса текущего дня, он показываетв предыдущий или следующий день текущего дневного пояса, и когда я добавил свои акции, отметка времени указывается за день до того, как я смотрю на консоль рельсов

My schema.rb

ActiveRecord::Schema.define(version: 2018_11_28_183416) do

  create_table "friendships", force: :cascade do |t|
    t.integer "user_id"
    t.integer "friend_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["friend_id"], name: "index_friendships_on_friend_id"
    t.index ["user_id"], name: "index_friendships_on_user_id"
  end

  create_table "notes", force: :cascade do |t|
    t.string "content"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "user_id"
    t.index ["user_id"], name: "index_notes_on_user_id"
  end

  create_table "stocks", force: :cascade do |t|
    t.string "ticker"
    t.string "name"
    t.decimal "last_price"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "user_stocks", force: :cascade do |t|
    t.integer "user_id"
    t.integer "stock_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["stock_id"], name: "index_user_stocks_on_stock_id"
    t.index ["user_id"], name: "index_user_stocks_on_user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "first_name"
    t.string "last_name"
    t.string "time_zone", default: "UTC"
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

end

например , enter image description here enter image description here

Как я могу решить эту проблему?

Примечание : Если требуется дополнительная информация, пожалуйста, дайте мне знать

Примечание: для краткости это мое репо

Примечание: моя конфигурация не показывает надежного поведения вообще, и я очень запутался: / и яve та же проблема для заметки текущего дня

---- update -------------------

В моих рельсах консоль

enter image description here

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

создайте миграцию с этим содержимым, чтобы удалить значение по умолчанию для selected_at, чтобы оно не заполнялось по умолчанию на уровне базы данных.

change_column_default(:user_stocks, :created_at, nil)

после этого, когда вы создаете новый UserStock, вам нужно указатьзначение create_at, и там вы можете указать create_at с датой пользователя, заботясь о часовом поясе.

UserStock.create(created_at: Time.now.in_time_zone(user.time_zone).to_time...)

или вы можете просто добавить его к обратному вызову модели, чтобы он выполнялся автоматически каждый развы создаете UserStock, он меняет значение

class UserStock < ActiveRecord::Base
  before_create :set_created_at

  private
    def set_created_at
      self.created_at = time.now.in_time_zone(self.user.time_zone).to_time
    end
end

, поэтому каждый раз, когда вы его создаете, значение является правильным.при этом он может работать как положено.

Другой вариант, если он вам не нужен только для этой конкретной модели и использовать их для всего взаимодействия с пользователем, вы можете создать на контроллере приложения фильтр before для установкичасовой пояс динамически, что-то вроде

class ApplicationController < ActionController::Base
  before_filter :set_time_zone

  def set_time_zone(&block)
    time_zone = current_user.try(:time_zone) || 'UTC'
    Time.use_zone(time_zone, &block)
  end
end
0 голосов
/ 04 декабря 2018

Вы пробовали запрос, указав диапазон?

Потому что вы пытаетесь найти user_stocks, которые были созданы в определенный день.Но обратите внимание, что created_at является datetime объектом, и я предполагаю, что ваша переменная date может быть просто date объектом.

def stock_by_date(date)
  UserStock.where(created_at: date.midnight..date.end_of_day, user_id: current_user.id)
end
...