【问题标题】:Route Controller#show method like how Controller#index would in Rails路由 Controller#show 方法,就像在 Rails 中的 Controller#index 一样
【发布时间】:2018-02-13 09:02:08
【问题描述】:

大家好,我是 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'

现在我的高压页面无法呈现。

更新解决方案:

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

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

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

特别感谢下面提供了很多帮助的人。 Nathanvda、rwold 和 Tai。

【问题讨论】:

  • 1 是帖子 ID?
  • @Tai,是的,我已经处理了那部分。我需要的是删除 /posts/ 部分。
  • 你的路线看起来怎么样?
  • @Tai,感谢您的评论。我更新了我的问题。

标签: ruby-on-rails rails-routing high-voltage


【解决方案1】:

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

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

但这是一条包罗万象的路线,如果没有定义其他路线,这将捕获所有路线,也包括您的 HighVoltage,如果它被配置为在 root 上提供页面。您现在有两个通用功能:一个用于查找静态页面,另一个用于查找帖子。

在这种情况下,最好的解决方案是让静态页面明确(因为我假设不会有那么多?)

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

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

像这样添加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 

当然我没有测试这段代码,但我认为这应该让你开始。除了渲染帖子,您还可以重定向到帖子控制器,这可能更容易(您将完全使用PostsController),但会添加重定向并更改网址。

在你的路由中你必须写

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

【讨论】:

  • 感谢@nathanvda 的回答。不幸的是,该项目要求从 url 的第一段呈现来自 High_voltage 的动态和静态页面。我们确实有很多静态页面,老板不接受将高压移动到单独的路线。
  • 那么你将不得不编写你自己的家庭控制器,我认为这将首先查找一个页面,然后查找一个帖子(反之亦然)。这一点也不难。这有意义吗?或者你需要一个例子来解决这个问题吗?
  • 我添加了一个示例,没有经过测试,但应该可以工作(希望如此)。它会首先尝试找到帖子并渲染它,否则会执行高压通常会执行的操作。
  • 感谢@nathanvda。这有点类似于我们团队所寻求的解决方案,除了不是创建一个额外的控制器来检查 Post 是否存在,而是在 routes.rb 文件中完成检查。像这样:constraints(lambda { |req| Post.exists?(req.params["id"]) }) do get '/:id' =&gt; 'posts#show', as: :article end。所以从技术上讲,这是最接近的答案。非常感谢!
  • 你应该回答你自己的问题,因为这确实是一个我忘记考虑的好方法(即使我以前用过,doh!)
【解决方案2】:

在您的routes.rb 文件中:

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

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

OP 评论后编辑: as: :sample_post 子句应该创建一个可以作为&lt;%= link_to "Show", sample_post %&gt; 调用的助手sample_post_path

【讨论】:

  • 好的,这里出了什么问题并不明显。您能否发布 1) 您的整个 routes.rb 文件 2) 文件 config/initializers/high_voltage.rb。 3) 您尝试访问静态页面的某种示例,包括您正在调用的路由和静态页面的目录路径?
  • 对不起,我不清楚描述这一点。我想要这个:&lt;%= link_to 'Show', post %&gt; 来呈现指向domain.com/1-sample-post 的链接,而不是默认的:domain.com/posts/1-sample-post
  • 我该怎么做,应该创建一个辅助部分?
  • 就像我在帖子中写的那样,您无需再做任何事情。我说“应该”是因为我还没有测试过它是否有效!
  • 好的,谢谢。我只是想我应该问一下,因为感觉这是我现在需要知道的最后一件事来解决这个问题,我对 Rails 很陌生,我不知道该怎么做。无论如何,谢谢。
猜你喜欢
  • 2018-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-21
  • 2011-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多