Rails:使用范围来显示模型的不同子集以及如何以较少 DRY 的方式构建它?
Posted
技术标签:
【中文标题】Rails:使用范围来显示模型的不同子集以及如何以较少 DRY 的方式构建它?【英文标题】:Rails: Using scopes to show different subsets of a model and how to build this the less DRY-ist way? 【发布时间】:2022-01-23 17:26:56 【问题描述】:我的 Ruby on Rails 应用程序中有一个模型电影,我想要一些简单的链接来显示它的不同子集 - 例如,未看过的电影、没有输入制作年份的电影、评级为“很棒”等。
我在我的电影模型中为所有这些条件创建了范围,例如。 g.
scope :no_year, -> where(release_year: [0, nil, ""])
但是我想要一个这些子集的列表 - 如前所述,用户可以单击并在默认视图(实际上是电影索引视图)中获得结果的链接列表。所以我有一个链接列表,如下所示,这要求我为所有这些看起来几乎相同的范围添加路由和方法。
<%= link_to 'Movies without a Year', noyear_movies_path %>
(<%= Movie.no_year.count %>)
routes.rb:
resources :movies do
get :noyear, on: :collection
end
movies_controller.rb:
def noyear
@q = Movie.no_year.ransack(params[:q]) # using Ransack for a sidebar that is displayed
@pagy, @movies = pagy(@q.result(distinct: true)) # using pagy to split up results
render 'index'
end
编辑:添加索引和侧边栏方法代码。
我的索引方法如下所示:
def index
@pagy, @movies = pagy(@q.result(distinct: true))
end
...变量 q 本身是在应用程序范围内设置的,因为它是在包含始终显示的小搜索字段的边栏中定义的:
def sidebar_q_movie
@q = Movie.ransack(params[:q])
end
我相信这可以更好地实现。但由于我对 Ruby 还很陌生,所以我不知道。任何提示表示赞赏!
【问题讨论】:
【参考方案1】:您可以使用 Movies#index
的查询参数指定过滤器,而不是为每个电影过滤器设置单独的路由
<%= link_to 'Movies without a Year', movies_path(filter: 'no_year') %>
在控制器中:
def index
@movies = Movies.send(params[:filter])
end
当然,您需要先验证过滤器参数,然后再发送到Movies
。
【讨论】:
谢谢你,这很有趣。但是我正在使用 ransack,并且我在原始问题中添加了我的索引方法的外观。 没关系 - 我想通了 :) 我需要链接它,...Movie.send(params[:filter].ransack(params[:q]),这似乎有效。以上是关于Rails:使用范围来显示模型的不同子集以及如何以较少 DRY 的方式构建它?的主要内容,如果未能解决你的问题,请参考以下文章