如何解决重构!如何在数据库查询中重新使用变量以在Rails控制器中检索数据
我正在尝试重构我的Rails API中的代码,该代码发送图表的分析数据( 目前正在运行 )。因为我在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,range: 4.weeks.ago.midnight..Time.zone.now
).count
goals = current_user.goals.group_by_day(
:created_at,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,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 ... >>未定义的局部变量或方法`bookmarks
我尝试过current_user。[:type] ... >>“语法错误,未知[”
我尝试过current_user [:type] ... >> NameError(未定义的局部变量或方法“书签”
我尝试了current_user。%{type} ...&current_user。#{type} ...&current_user。$ {type}
任何指导都将不胜感激:)我对Ruby on Rails领域还很陌生,并且一旦我对如何重用传递到变量中的变量有了更好的了解,我期待看到我的代码变得更加干燥。数据库查询
解决方法
要改善Spickerman的答案-您应该考虑从控制器中提取商务逻辑并将其放置在其所属的模型中:
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
,
您非常接近解决方案。只需使用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,range: 4.weeks.ago.midnight..Time.zone.now
).count
end
@bookmarks = fetch_activity(bookmarks)
@goals = fetch_activity(goals)
@journals = fetch_activity(journals)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。