关于Rails 3中嵌套路由的混淆,特别是自动生成的路径

时间:2010-10-23 00:37:43

标签: ruby-on-rails ruby-on-rails-3

对于每个物种,我有很多数据集。对于每个数据集,我有许多表型。数据集的名称在一个物种中是主键。该物种也具有弦键主键(例如,智人(Homo sapiens)的Hs)。所以,我希望能够如下指定表型:

/species/Hs/mcgary/1

其中mcgary是表型集的名称(slug)。

我知道我可以通过在routes.rb文件中添加以下行来获得此类结果:

match "/species/:species_id/:dataset(/:id/:action)" => 'phenotypes'
match "/species/:species_id/:dataset/:id" => 'phenotypes#show'

表型是表型控制者。物种有一个控制器,但数据集没有 - 它的功能由物种和Phenotype的控制器处理。)

不幸的是,这并不能保证路径能够正常工作,例如edit_species_dataset_phenotype_path。我不太确定如何在routes.rb中编写该指令。一种可能性是除了匹配指令之外还有以下内容:

resources :species do
  resources :dataset do
    resources :phenotypes
  end
end

并设置重定向。但那很尴尬。有什么方法可以使用匹配符号来使路径工作?喜欢新的路线,但希望文档中有一些完整的例子。

我还注意到,如果我执行类似edit_species_dataset_path(种类,数据集)的操作,我可以获得/species/:species_id/:phenotype_set_id路由格式 - 但我不确定如何使用它:在Species上使用abbrev,除了每次都输入species.abbrev。有没有办法告诉它默认使用该列,而不是id?

非常感谢。 (是的,我意识到像这样的嵌套路线变得尴尬。我很好。)

1 个答案:

答案 0 :(得分:1)

我找到了一个不完美的解决方案,这是:path上的resources()选项。

resources :species do
  resources :datasets do
    resources :phenotypes, :path => ""
  end
end

这让我对我想要的路线略有不同,而且有三个控制器而不是两个,这并不理想 - 但重要的是,它有效。

我的路径现在的形式为/ species / Hs / datasets / mcgary / 1(表型1)。

我还必须在ApplicationHelper中编写一些辅助方法。这使得拥有三重嵌套资源变得容易一些。

def phenotype_path(phenotype, dataset=nil, species=nil)
  dataset ||= phenotype.dataset
  species ||= phenotype.species
  File.join(phenotypes_path(dataset, species), phenotype.id.to_s)
end

def phenotypes_path(dataset, species=nil)
  species ||= dataset.species
  File.join(species_path(species.abbrev), "datasets", dataset.name)
end

def edit_phenotype_path(phenotype, dataset=nil, species=nil)
  File.join(phenotype_path(phenotype,dataset,species), "edit")
end

def new_phenotype_path(dataset, species=nil)
  File.join(phenotypes_path(dataset, species), "new")
end

alias :dataset_path :phenotypes_path

def edit_dataset_path(dataset, species=nil)
  File.join(dataset_path(dataset, species), "edit")
end

def dataset_path(dataset, species=nil)
  species ||= dataset.species
  File.join(species_path(species.abbrev), "datasets", dataset.name)
end

def datasets_path(species)
  species_datasets_path(species.abbrev)
end

不幸的是,这些路径有时似乎与自动生成的路径冲突。我不确定哪个模块包含这些路径,因此很难重写它们。

另一个问题是我无法弄清楚如何做物种_路径(物种)并让它使用缩写。相反,我必须做物种_路径(species.abbrev)。