路由 Controller#show 方法就像 Controller#index 在 Rails 中的方式

Route Controller#show method like how Controller#index would in Rails

大家好,我是 rails 的新手。对不起,如果我不能正确定义这个问题。

我想要的是:

domain.com/posts/1-sample-post

路由如下:

domain.com/1-sample-post

如何在 rails 路线中实现这一点?我已经尝试搜索了将近 3 个小时。这在 PHP 框架中非常容易。我认为这在 Rails 中也很容易。

我忘了说我在我的静态页面应用程序中安装了 High_voltage gem。

是否这样做:

#routes.rb
resources :posts
get '/:id' => 'posts#show'

现在无法呈现我的 High_voltage 页面。

更新解决方案:

所以这是我们在路线中所做的:

Rails.application.routes.draw do
  resources :authors
  constraints(lambda { |req| Author.exists?(slug: req.params["id"]) }) do
     get '/:id' => 'authors#show'
  end

  devise_for :users

  resources :posts
  constraints(lambda { |req| Post.exists?(slug: req.params["id"]) }) do
    get '/:id' => 'posts#show'
  end
end

请注意,仅使用 exists 很重要?在这里查询,因为它比其他方法非常快,所以它不会占用那么多的加载时间来呈现一条记录。

特别感谢以下帮了大忙的小伙伴们。 Nathanvda、rwold 和 Tai。

在您的 routes.rb 文件中:

get '/:id-sample-post', to: 'posts#show', as: :sample_post

假设 posts 是您的控制器,show 是调用具有给定 ID 的文章视图的操作。

在操作评论后编辑: as: :sample_post 子句应该创建一个可以作为 <%= link_to "Show", sample_post %>.

调用的助手 sample_post_path

所以另一个答案正确地建议了

get '/:id', to: 'posts#show'

但这是一个包罗万象的路由,如果没有定义其他路由,这将捕获所有路由,如果它被配置为在 root 上提供页面,也会捕获您的 HighVoltage。您现在有两个包罗万象的方法:一个用于查找静态页面,一个用于查找 post。

这种情况下的最佳解决方案,恕我直言,将静态页面显式化(因为我假设不会有那么多?)

get '/about' => 'high_voltage/pages#show', id: 'about'
get '/:id' => 'posts#show'

如果你有很多页面,似乎最简单的方法就是在不同的路线上呈现高压?例如。像

get '/pages/:id' => 'high_voltage/pages#show' 
get '/:id' => 'posts#show' 

在这两种情况下,由于我们使用显式路由,您必须在高压初始化程序中禁用默认路由:

# config/initializers/high_voltage.rb
HighVoltage.configure do |config|
  config.routes = false
end

[更新:添加特殊控制器以同时考虑 post 和页面]

像这样添加一个HomeController

class HomeController < ApplicationController

  # include the HighVoltage behaviour --which we will partly overwrite 
  include HighVoltage::StaticPage    

  def show
    # try to find a post first 
    @post = Post.where(id: params[:id).first 
    if @post.present? 
      render 'posts/show'
    else 
      # just do the high-voltage thing
      render(
        template: current_page,
        locals: { current_page: current_page },
      )
    end 
  end 
end 

当然我没有测试这段代码,但我认为这应该能让你入门。除了渲染 post,您还可以重定向到 posts-controller,这可能更容易(并且您将完全使用 PostsController),但会添加一个重定向并将更改 url.

在你的路由中你将不得不写

get '/:id', 'home#show'