Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 我可以有相同的URL,但不同的动态段吗?_Ruby On Rails_Ruby_Rails Routing - Fatal编程技术网

Ruby on rails 我可以有相同的URL,但不同的动态段吗?

Ruby on rails 我可以有相同的URL,但不同的动态段吗?,ruby-on-rails,ruby,rails-routing,Ruby On Rails,Ruby,Rails Routing,是否可以使用相同的URL,但使用不同的动态段 我的问题是:我希望能够将对象A添加到对象B和C。所以我想要两条铁路路线,A/new/:b_id和A/new/:c_id。我试过了 在my routes.rb中: controller :A do get 'A/new/:b_id', to: 'A#new', as: :new_b_a get 'A/new/:c_id', to: 'A#new', as: :new_c_a end 问题是传递到新页面的值总是params[:b_id]!(我

是否可以使用相同的URL,但使用不同的动态段

我的问题是:我希望能够将对象
A
添加到对象
B
C
。所以我想要两条铁路路线,
A/new/:b_id
A/new/:c_id
。我试过了

在my routes.rb中:

controller :A do
  get 'A/new/:b_id', to: 'A#new', as: :new_b_a
  get 'A/new/:c_id', to: 'A#new', as: :new_c_a 
end
问题是传递到新页面的值总是
params[:b_id]
!(我可以使用
params[:b_id]
从URL打印出值)


所以,似乎我不可能有两条具有不同动态段的类似路线。。?如果是这样的话,我将如何做到这一点?

路由系统的工作原理是尝试将当前路径从上到下匹配到每个已注册的路由。动态
:b_id
部分表示“路径中的任何内容都将作为名为
:b_id
的参数传递给控制器”。因此,向
“a/new/anywhere”
发出请求将始终与第一个路由匹配,并且由于您将参数重命名为
:new_b_a
,因此在
参数
散列中就是这样调用的

如果确实要使用相同的路由,则需要传递一个额外的参数,指定要创建关系的类,尽管我不建议这样做。它可能类似于
get'A/new/:klass/:id'
,因此在控制器中,您可以将参数与所需的类相匹配:

def new
  case params[:klass]
  when 'B' then # do stuff
  when 'C' then # do stuff
  else raise "Invalid class: #{params[:klass]}"
  end
end

路由系统的工作原理是,从上到下,尝试将当前路径与每个已注册的路由相匹配。动态
:b_id
部分表示“路径中的任何内容都将作为名为
:b_id
的参数传递给控制器”。因此,向
“a/new/anywhere”
发出请求将始终与第一个路由匹配,并且由于您将参数重命名为
:new_b_a
,因此在
参数
散列中就是这样调用的

如果确实要使用相同的路由,则需要传递一个额外的参数,指定要创建关系的类,尽管我不建议这样做。它可能类似于
get'A/new/:klass/:id'
,因此在控制器中,您可以将参数与所需的类相匹配:

def new
  case params[:klass]
  when 'B' then # do stuff
  when 'C' then # do stuff
  else raise "Invalid class: #{params[:klass]}"
  end
end

实现这一点的更好方法是使用

您总是会得到
:b_id
,因为Rails按照路径在文件中出现的顺序匹配路径。由于
B
ID是一个与
C
ID无法区分的整数,因此它无法知道您想要一个还是另一个

但是,由于您已经有了
B
s和
C
s,并且可能还需要创建、显示这些路径,因此您可以RESTful地区分它们的路径,这也是Rails希望您做的

# config/routes.rb
resources :bs do
  resources :as
end

resources :cs do
  resources :as
end    
这将为您构建手动创建的路径,但有一点改变:

/bs/:b_id/as/new
/cs/:c_id/as/new
如您所见,路径现在以您想要添加
A
的对象类型开始,因此Rails可以将它们区分开来。为此生成的帮助器方法看起来与您当前手动定义的方法相同:

new_b_a_path(b)
new_c_a_path(c)
这两条路径都会将您路由到
AsController
,然后您需要根据当前的参数查找正确的
B
C

# AsController#new
@parent = B.find(params[:b_id]) if params[:b_id]
@parent = C.find(params[:c_id]) if params[:c_id]
@a = parent.build_a # Assuming has_one or has_many from B and C to A

Rails花了很长时间开发了一种特殊的方法来完成这类事情。您可以随时投入并以不同的方式进行,但充其量您将浪费精力,最坏的情况下,您将与框架抗争。该框架不那么折衷,通常是成功的。

实现这一点的更好方法是使用

您总是会得到
:b_id
,因为Rails按照路径在文件中出现的顺序匹配路径。由于
B
ID是一个与
C
ID无法区分的整数,因此它无法知道您想要一个还是另一个

但是,由于您已经有了
B
s和
C
s,并且可能还需要创建、显示这些路径,因此您可以RESTful地区分它们的路径,这也是Rails希望您做的

# config/routes.rb
resources :bs do
  resources :as
end

resources :cs do
  resources :as
end    
这将为您构建手动创建的路径,但有一点改变:

/bs/:b_id/as/new
/cs/:c_id/as/new
如您所见,路径现在以您想要添加
A
的对象类型开始,因此Rails可以将它们区分开来。为此生成的帮助器方法看起来与您当前手动定义的方法相同:

new_b_a_path(b)
new_c_a_path(c)
这两条路径都会将您路由到
AsController
,然后您需要根据当前的参数查找正确的
B
C

# AsController#new
@parent = B.find(params[:b_id]) if params[:b_id]
@parent = C.find(params[:c_id]) if params[:c_id]
@a = parent.build_a # Assuming has_one or has_many from B and C to A

Rails花了很长时间开发了一种特殊的方法来完成这类事情。您可以随时投入并以不同的方式进行,但充其量您将浪费精力,最坏的情况下,您将与框架抗争。该框架不太妥协,通常会获胜。

好主意,投赞成票……但我认为@kristjen的答案更符合rails的要求。不过,谢谢你的解释!好主意,投赞成票……但我认为@kristjen的答案更符合rails的要求。不过,谢谢你的解释!