Rails 6: Как использовать generate_series, чтобы показать, было ли действие выполнено в данный день - PullRequest
0 голосов
/ 06 мая 2020

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

completed_habit.rb

  belongs_to :user
  belongs_to :habit

У меня есть метод в моей модели Habit, который я хотел бы создать массив дат со значением 1 или 0, а затем я просто l oop через этот массив в представлении и показать X или чек.

  def sequence

    query = <<-SQL
      SELECT
        series_date,
        COUNT(habit_id) AS completed
      FROM generate_series(
             ( SELECT created_at::date FROM habits
               WHERE habits.id = :user_id
             ),
             CURRENT_DATE,
             '1 day'
           ) AS series_date
      LEFT JOIN completed_habits ON completed_habits.created_at::date = series_date
      WHERE habit_id = :habit_id
      AND user_id = :user_id
      GROUP BY series_date
      ORDER BY series_date DESC;
    SQL

    Habit.find_by_sql([query, { user_id: self.user, habit_id: self.id } ])

  end

Когда я запускаю этот запрос в Postico, я получаю следующее, которое почти готово (я бы предпочел, чтобы строка для дат, для которых в этот день не указано completed_habit с завершенным значением 0):

enter image description here

Однако, когда я визуализирую @habit .sequence в моем представлении Rails, я получаю следующее:

enter image description here

Я не понимаю, почему он не возвращает series_date, привычку_id и завершено значения, которые я вижу в Postico.

ОБНОВЛЕНИЕ:

Использование Model.connection.exec_query Теперь у меня это работает, но все еще кажется довольно привлекательным нкий мне. Есть ли более чистый, более "Railsy" способ сделать это?

  def sequence

    query = <<-SQL
      SELECT
        series_date,
        COUNT(habit_id) AS completed
      FROM generate_series(
             ( SELECT created_at::date FROM habits
               WHERE habits.id = $1
             ),
             CURRENT_DATE,
             '1 day'
           ) AS series_date
      LEFT JOIN completed_habits ON completed_habits.created_at::date = series_date
      GROUP BY series_date
      ORDER BY series_date ASC;
    SQL

    binds = [
      ActiveRecord::Relation::QueryAttribute.new("habit_id", self.id, ActiveRecord::Type::Integer.new)
    ]

    Habit.connection.exec_query(query, 'sql', binds).to_a

  end

schema.rb

  create_table "completed_habits", force: :cascade do |t|
    t.integer "user_id"
    t.integer "habit_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "habits", force: :cascade do |t|
    t.string "name"
    t.integer "user_id"
    t.string "frequency"
    t.boolean "is_active"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.text "description"
  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", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.string "name"
    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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...