У меня есть модель 'work_space', которая имеет 'много' обзоров '. В моей модели 'обзоры' пользователи могут оценивать рабочее пространство с целым числом, хранящимся в столбце :rating
. Я создал метод в своей модели WorkSpace для вычисления среднего значения всех обзоров для определенного рабочего пространства.
класс WorkSpace
def avg_rating
reviews.average(:rating).to_f
end
Я добавил этот метод в свой сериализатор WorkSpace, и он возвращает данные, которые я ищу ,
Затем я создал метод в моей модели WorkSpace, который вычислял бы 5 самых высоких «оцененных» рабочих пространств.
класс WorkSpace
scope :by_average_for, ->(column) {
joins(:reviews)
.group('work_spaces.id')
.order(Arel.sql("AVG(reviews.#{column}) desc"))
.having("AVG(reviews.#{column}) > 4", column) if column
}
def top_avg_rating
WorkSpace.by_average_for(:rating).limit(5)
end
Проблема, с которой я здесь сталкиваюсь, заключается в том, что когда я получаю данные для top_avg_rating
, в нем перечислены правильные рабочие области, но я получаю только те данные, которые присутствуют в моей схеме WorkSpace, и не добавленные данные, которые я обычно получаю от моего сериализатора WorkSpace. Наиболее важно, что avg_rating
отсутствует.
create_table "work_spaces", force: :cascade do |t|
t.string "place_id"
t.float "lat"
t.float "lng"
t.bigint "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name"
t.string "address"
t.string "photo"
t.integer "cached_votes_total", default: 0
t.integer "cached_votes_score", default: 0
t.integer "cached_votes_up", default: 0
t.integer "cached_votes_down", default: 0
t.integer "cached_weighted_score", default: 0
t.integer "cached_weighted_total", default: 0
t.float "cached_weighted_average", default: 0.0
t.index ["user_id"], name: "index_work_spaces_on_user_id"
end
Я подумал, что было бы неплохо сохранить / кэшировать данные, которые я получаю из моей модели WorkSpace, в новый столбец. Поэтому я добавил столбец в свою модель WorkSpace.
t.float "avgrating"
Затем я попытался сохранить данные для моего avg_rating
в этом столбце.
Класс WorkSpace
def update_rating
reviews.average(:rating).to_f
update(avgrating: reviews.average(:rating).to_f)
end
Это на самом деле работает, но я должен добавить этот метод в мой сериализатор, чтобы обновить столбец. Есть ли другой способ убедиться, что этот метод вызывается? Я изучил after_save
вариантов и кэширование, но я не смог собрать воедино ничего, что имело бы смысл.
Мне кажется, что должен быть лучший способ добиться этого, и у меня есть сильное чувство, что я возможно, все это неправильно.
Мне нужно создать эту же логику c для нескольких полей из моей таблицы отзывов, поэтому я надеюсь найти хороший способ сделать это, прежде чем двигаться вперед .