Ruby on rails 更正Rails中的无效资源路由

Ruby on rails 更正Rails中的无效资源路由,ruby-on-rails,ruby-on-rails-3,ruby-on-rails-3.2,routes,nested-routes,Ruby On Rails,Ruby On Rails 3,Ruby On Rails 3.2,Routes,Nested Routes,在Rails中使用嵌套资源路由时我注意到的一点是,从技术上讲,用户可以访问子资源所在的路由(因此可以正确显示),但父资源的id表示的对象实际上与子资源无关 例如,在路由users/:user\u id/post/:id中,用户可以键入一个路由,其中:user\u id表示未将post与:id对应的用户 解决此问题的最佳方法是什么,以便在用户访问无效URL时,服务器将用户重定向到正确的URL 我已经在我的控制器中添加了一些代码来处理这个问题,但是必须检查每个控制器操作中的路径,然后将用户重定向到适

在Rails中使用嵌套资源路由时我注意到的一点是,从技术上讲,用户可以访问子资源所在的路由(因此可以正确显示),但父资源的id表示的对象实际上与子资源无关

例如,在路由
users/:user\u id/post/:id
中,用户可以键入一个路由,其中
:user\u id
表示未将post与
:id
对应的用户

解决此问题的最佳方法是什么,以便在用户访问无效URL时,服务器将用户重定向到正确的URL

我已经在我的控制器中添加了一些代码来处理这个问题,但是必须检查每个控制器操作中的路径,然后将用户重定向到适当的url,这有点尴尬,特别是因为每个操作的url帮助程序都是不同的

编辑用户帖子路径(@user,@post)
新建用户帖子路径(@user,@post)


必须有更好的方法,对吗?

首先,您应该知道ROR引发的错误将在生产环境中显示消息“对不起,您正在查找的页面不存在”

因此,我不会担心这一点。如果您想“捕获”故障并快速重定向到安全区域,您可能有兴趣使用
rescue
方法


玩得开心

您应该在所有请求上运行
前过滤器
,以确保用户有效。如果没有,它将抛出
ActiveRecord::RecordNotFound
,并显示友好的404页面

然后根据您需要的用户抓取帖子,无论是在另一个
过滤器之前,还是直接在操作中。根据用户进行帖子搜索。下面的示例演示了如何在过滤器之前使用另一个
执行此操作

before_filter :find_user_by_user_id
before_filter :find_post

def show
  # Use @post variable here however you need
end

private

def find_user_by_user_id
  @user = User.find(params[:user_id])
end

def find_post
  # This assumes you have an association set up as needed
  @post = @user.posts.where(id: params[:id]).first

  if @post.nil?
    # Do whatever you need here
  end
end

但是什么触发了错误呢?Rails是否会自动检查父资源是否正确并做出相应的反应?注意,在我的示例中,
Post.find(params[:id])
将返回一个有效的Post,而
User.find(params[:User_id])
也将是有效的,但是
User.find(params[:User_id]).posts.include?(Post.find(params[:id])和
Post.find(params[:id]).User==User.find(params[:User_id])
两者都将为false。该错误由关系中返回的类触发。当您试图查找id为user的资源时,作为嵌套资源,他的帖子将返回一个数组。一旦您选择使用params[:id]从show action中的数组中分离特定的post,当找不到id时,它将在数组中搜索id,返回nil并呈现404输出。因此。。。它保存索引操作中的资源数组,并对照show操作中返回的资源进行检查?我很困惑。。。仅供参考,在我的开发环境中,当我给出一个类似于示例中的路由时,不会返回任何错误。它将提交的资源与先前提交的关系资源相匹配。在dev上没有出现错误的原因是,您在development.rb中设置了config.consive_all_requests_local=true。如果设置为false,它将呈现用户友好的输出(404),这很奇怪。我更改了你提到的变量,但它仍然没有给我任何错误。(除非父资源根本不存在。)也许您不了解这种情况,下面是一个例子:用户以某种方式访问了
users/3/posts/5
。控制器运行
@user=user.find(3)
@post=post.find(5)
。已找到@user和@post并返回有效的ActiveRecord对象。Rails的哪个部分会检查
@user.posts.include?(@post)
是否为真,如果不是,则抛出异常?啊,我明白了。如果我只在用户帖子的范围内搜索帖子,我就不会有这个问题。到目前为止,我一直在分别搜索帖子。例如,
Posts.find(参数[:id])