首页 > 解决方案 > 在 Rails 5 中自动管理多个类别的自定义范围

问题描述

我是 Rails 5 的新手,正在从事一个项目,其中每个类别都有一个页面,并且只会显示具有特定或相同类别的博客项目。

例如:博客标题 1 到博客标题 5 具有类别“技术”,博客标题 6 到博客标题 8 具有类别“商业”。

如果我点击 http://localhost:3000/blogs/tech 它将显示博客标题 1 到 5,如果我点击 http://localhost:3000/blogs/business 它将显示博客标题 6 到 8。

为此,我尝试在我的博客控制器上创建自定义范围:

class BlogsController < ApplicationController
 def index
    @blogs = Blog.all
  end

  def business
    @blogs = Blog.business
  end 
end 

然后在我的博客模型上:

class Blog < ApplicationRecord

def self.business
    where(post_category: 1)
 end 

end 

我还为我的业务方法创建了一个新视图来显示所有业务类型类别的博客项目,并在我的 index.html.erb 文件中复制了相同的内容:

<p id="notice"><%= notice %></p>

<h1>Post Category 0</h1>

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Body</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @blogs.each do |blog| %>
      <tr>
        <td><%= blog.title %></td>
        <td><%= blog.body %></td>
        <td><%= link_to blog.status, toggle_status_blog_path(blog) %></td>
        <td><%= blog.post_category.title %></td>
        <td><%= link_to 'Show', blog %></td>
        <td><%= link_to 'Edit', edit_blog_path(blog) %></td>
        <td><%= link_to 'Destroy', blog, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Blog', new_blog_path %>

最后我更新了我的路线:

  get 'blogs/business', to: 'blogs#business'

虽然这适用于单个项目。如果每次我创建一个新类别时,手动放置它是行不通的,而且我不确切知道应用程序的用户将在类别标题上添加什么。如何以编程方式执行此操作,以便每次创建新类别时都会创建新页面,而不是每次手动添加并创建视图?

有没有办法做到这些?

旁注:博客和 PostCategory 表通过 post_category_id 相互关联。

标签: ruby-on-rails

解决方案


您不必在此处使用范围。仅用于BlogsController#show显示给定类别的帖子。

首先为(在数据库中)添加一个slug字段。PostCategory现在您title在 URL 中使用,但必须将其更改为转义值(不含空格、特殊字符等)。

您可能可以使用 gem 来完成,或者您可以使用我的 gist中的代码。请记住将其调整为您的模型和字段。

然后,添加一个路由 ( routes.rb):

get 'blog/:slug', to: 'blogs#show', as: :blog_category

最后,在您的BlogsController, addshow方法中:

def show
  category = PostCategory.find_by(slug: params[:slug])
  @blogs   = Blog.where(post_category: category.id)
end

就这样。当然,您可以show通过允许参数进行修改,添加joins并执行单个查询以获取博客,但这可以稍后完成。


推荐阅读