Rails 渲染静态页面时路由冲突

Rails Routing Clash When Rendering Static Pages

我有路由冲突。将我所有的博客文章从 /posts/:id 移动到 /:id(这很好)后,我现在遇到一个问题,我的静态页面不包含 ID,因此它们不会呈现。我不想通过我的帖子控制器处理它们。

这是我目前在 routes.rb 文件中的内容:

  resources :posts, only: [:index, :create, :edit, :new, :destroy]
  get '/:id' => 'posts#show', :as => 'custom_url'
  match '/posts/:id' => redirect('/%{id}', status: 301)

但是现在这些都不起作用了...

  match '/privacy' => 'static#privacy'
  match '/terms' => 'static#terms'

我有一个名为 static_controller.rb 的控制器,如果需要我可以使用它。我怎样才能跳过 /:id 比赛。

更新:

还遇到了我的 def 更新没有更新我的内容的问题。

  def update
    @post = Post.find(params[:id])

    respond_to do |format|
      if @post.update_attributes(params[:post])
        format.html { redirect_to @post, :notice => 'Post was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render :action => "edit" }
        format.json { render :json => @post.errors, :status => :unprocessable_entity }
      end
    end
  end

Rails按照从上到下的顺序匹配路由,越往上优先级越高。参见 Rails Routing from the Outside In。如果你移动这些路线

  match '/privacy' => 'static#privacy'
  match '/terms' => 'static#terms'

在这些路由之上,静态路由将优先于博客 posts 并且应该正确呈现。

  resources :posts, only: [:index, :create, :edit, :new, :destroy]
  get '/:id' => 'posts#show', :as => 'custom_url'
  match '/posts/:id' => redirect('/%{id}', status: 301)

注意,这意味着如果您有任何博客 post id 与静态页面路由冲突,静态页面将匹配并显示。

为避免您所描述的情况,您不应匹配并绕过 /posts/ 重定向。这打破了 rails 层次结构和顺序模式,并可能使您的代码比它需要的更混乱。 @Chris Selemers 的回答是正确的,但正如他指出的那样,这种方法存在潜在的(如果非常有限的话)风险。

get '/posts/:id' => 'posts#show', :as => 'custom_url'

或者更好的做法是:

resources :posts