Я пытаюсь реорганизовать код в моем API-интерфейсе rails, который отправляет аналитические данные для диаграмм ( в настоящее время работает ). Поскольку у меня такой же код выполняется для 1. Закладки, 2. Журналы, 3. Цели, и это не очень сухо.
Я пытаюсь создать 1 запрос к базе данных (используя PostgreSQL), который может получать тип (закладка, цель, журнал) в качестве параметра ... Я пробовал использовать [: type] и жестко кодировать «тип», где закладка использовалась для пример...
Существующий (рабочий) код, который я хочу реорганизовать:
class AnalyticsController < ApplicationController
before_action :authenticate_user
def entries_by_date
bookmarks = current_user.bookmarks.group_by_day(
:created_at,
format: '%Y-%m-%d',
range: 4.weeks.ago.midnight..Time.zone.now
).count
journals = current_user.journals.group_by_day(
:created_at,
format: '%Y-%m-%d',
range: 4.weeks.ago.midnight..Time.zone.now
).count
goals = current_user.goals.group_by_day(
:created_at,
format: '%Y-%m-%d',
range: 4.weeks.ago.midnight..Time.zone.now
).count
entries_array = []
entries_array.push(@bookmarks)
entries_array.push(goals)
entries_array.push(journals)
total_entries_by_date = entries_array.inject { |memo, el| memo.merge(el) { |_k, old_v, new_v| old_v + new_v } }
render json: {
total_entries_by_date: total_entries_by_date,
bookmarks: bookmarks,
goals: goals,
journals: journals
}
end
end
Я пробовал это:
....
def entries_by_date
def fetch_activity(type)
current_user[:type].group_by_day(
:created_at,
format: '%Y-%m-%d',
range: 4.weeks.ago.midnight..Time.zone.now
).count
end
@bookmarks = fetch_activity(bookmarks)
@goals = fetch_activity(goals)
@journals = fetch_activity(journals)
... (cont'd)
Я пробовал current_user.type ... >> undefined локальную переменную или закладки метода
Я пробовал current_user. [: Type] ... >> "Синтаксическая ошибка, неизвестно ["
Я пробовал current_user [: type] ... >> NameError (неопределенная локальная переменная или метод `закладки '
Я пробовал current_user.% {Type} ... & current_user. # {Type} ... & current_user. $ {Type}
Любые рекомендации будут очень признательны :) Я новичок в мире Ruby on Rails и с нетерпением жду, когда мой код станет немного суше, когда я лучше пойму, как повторно использовать переменные, передаваемые в запрос к базе данных
2 ответа
Вы были довольно близки к решению. Просто используйте public_send
и передать имя метода, который вы хотите вызвать, в виде строки или символа.
def entries_by_date
@bookmarks = fetch_activity(:bookmarks)
@goals = fetch_activity(:goals)
@journals = fetch_activity(:journals)
# ...
end
private
def fetch_activity(type)
current_user.public_send(type).group_by_day(
:created_at,
format: '%Y-%m-%d',
range: 4.weeks.ago.midnight..Time.zone.now
).count
end
@bookmarks = fetch_activity(bookmarks)
@goals = fetch_activity(goals)
@journals = fetch_activity(journals)
Чтобы немного улучшить ответ Спикермана - вам следует рассмотреть возможность извлечения бизнес-логики из контроллера и поместить ее в модель, к которой она принадлежит:
class User < ApplicationRecord
# Gets a single activity
def fetch_activity(type)
public_send(type).group_by_day(
:created_at,
format: '%Y-%m-%d',
range: 4.weeks.ago.midnight..Time.zone.now
).count
end
# Gets a hash containing the counts of the users activities and total
def fetch_activities(*types)
types.each_with_object({}) do |key, hash|
hash[key] = fetch_activity(key)
end.then do |hash|
hash.merge(total_entries_by_date: hash.values.sum)
end
end
# ...
end
Модели намного проще тестировать, чем контроллеры, поскольку вы можете просто настроить его и вызвать метод прямо на объекте, вместо того, чтобы идти через HTTP и анализировать ответ - это ключевая причина, по которой ваши контроллеры должны быть как можно более тонкими:
class AnalyticsController < ApplicationController
before_action :authenticate_user
def entries_by_date
render json: current_user.fetch_activities(:bookmarks, :goals, :journals)
end
end
Новые вопросы
ruby-on-rails
Ruby on Rails - это полнофункциональная платформа веб-приложений с открытым исходным кодом, написанная на Ruby. Он следует популярной модели фреймворка MVC и известен своим подходом «соглашение поверх конфигурации» при разработке приложений.