我可以使用相同的网址,但不同的动态网段吗?

时间:2015-07-09 13:50:20

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

是否可以使用相同的网址,但具有不同的动态细分?

我的问题是:我希望能够将对象A添加到对象BC。所以我希望有两个Rails路由,A/new/:b_idA/new/:c_id。我试过了。

在我的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]从网址打印出来的值。)

所以看起来我可能不会有2个不同动态段的相似路线..?如果是这样,我该怎么做?

2 个答案:

答案 0 :(得分:2)

路由系统的工作原理是尝试匹配每个已注册路由的当前路径,从上到下。动态:b_id部分表示"路径中的任何内容都将作为名为:b_id的参数传递给控制器​​"。因此,向"A/new/anything"发出请求将始终与第一条路线匹配,并且由于您将参数重命名为:new_b_a,因此它在params哈希中的调用方式

如果你真的想要使用相同的路线,你需要传递一个额外的参数来指定你想要创建关系的类,尽管我不建议这样做。它可能类似于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

答案 1 :(得分:2)

更好的方法是使用nested resources

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

但是,既然你已经拥有BC,也许还需要创建,显示等等,你可以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,然后您需要根据当前参数查找正确的BC

# 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花了很长时间开发一种特殊的方式来做这种事情。你总是可以潜入并以不同的方式去做,但最好的是你会浪费精力,最糟糕的是你将会与框架作斗争。该框架不那么妥协,通常会赢。