【发布时间】:2013-02-16 09:52:05
【问题描述】:
我正在重构我的应用程序以在任何地方使用 1 级深度嵌套资源,这是一个仅限 JSON 的 API。这是我的routes.rb 的精简版:
resources :measurements, only: [:index, :show] do
resource :tag_node, controller: :physical_nodes, only: [:show]
resource :anchor_node, controller: :physical_nodes, only: [:show]
resource :experiment, only: [:show]
end
resources :physical_nodes, only: [:index, :show] do
resources :tag_nodes, controller: :measurements, only: [:index]
resources :anchor_nodes, controller: :measurements, only: [:index]
end
resources :experiments, only: [:index, :show] do
resources :measurements, only: [:index]
end
还有我的精简版models:
class Measurement < ActiveRecord::Base
self.table_name = 'measurement'
self.primary_key = 'id'
belongs_to :physical_node, foreign_key: :tag_node_id
belongs_to :physical_node, foreign_key: :anchor_node_id
belongs_to :experiment, foreign_key: :experiment_id
end
class PhysicalNode < ActiveRecord::Base
self.table_name = 'physical_node'
self.primary_key = 'id'
has_many :measurements, foreign_key: :tag_node_id
has_many :measurements, foreign_key: :anchor_node_id
end
class Experiment < ActiveRecord::Base
self.table_name = 'experiment'
self.primary_key = 'id'
has_many :measurements, foreign_key: :experiment_id
end
1.:
什么有效:
-
GET /experiments/4/measurements.json工作正常
什么不起作用:(其他一切;))
GET /measurements/2/experiment.json
错误信息:
Processing by ExperimentsController#show as HTML
Parameters: {"measurement_id"=>"2"}
ActiveRecord::RecordNotFound (Couldn't find Experiment without an ID)
这应该很容易解决。更重要的是:
2.:
GET "/measurements/2/tag_node"
Processing by PhysicalNodesController#show as HTML
Parameters: {"measurement_id"=>"2"}
如何让 rails 将其称为 tag_node_id 而不是 measurement_id?
解决方案:
在与“dmoss18”长时间交谈后,很明显将tag_nodes 和anchor_nodes 作为physical_nodes 的子元素是没有意义的,因为它们只存在于测量表中。
所以现在我的routes.rb 看起来像这样:
resources :measurements, only: [:index, :show, :create]
resources :physical_nodes, only: [:index, :show]
resources :tag_nodes, only: [] do
resources :measurements, only: [:index]
end
resources :anchor_nodes, only: [] do
resources :measurements, only: [:index]
end
resources :experiments, only: [:index, :show] do
resources :measurements, only: [:index]
end
我还删除了所有only childs,因为这不是数据库的设计方式。
【问题讨论】:
-
#2:您的父资源是 :measurements。 Rails 自动假定 id 参数称为 [parent]_id,或在本例中为 measure_id。我相信这也是#1 失败的原因。当路由器传入 params[:measurement_id] 时,您的控制器操作 (ExeriementsController#show) 可能正在寻找 params[:id]。你可以阅读更多guides.rubyonrails.org/routing.html#nested-resources
-
问题 #1 有点不同。如果我调用
GET /measurements/2/experiment,然后在转到ExperiementsController#show时调用参数id(而不是measurement_id),我会得到id=2 的实验。但我想要的当然是:“给我一个measurement_id=2的实验”。好像我必须建立一个:if(params[:measurement_id]) then @experiement = Experiment.where("measurement_id = ?", params[:measurement_id])。还是有更简单的解决方案? -
正确。假设您没有使用experiment_id 来查找实验,而是使用measurement_id。我会发布答案
-
抱歉。你说得对。我必须
JOIN测量才能找到正确的实验,因为experiment_id 存储在测量表中。这使事情变得更加困难,但仍然可以使用if块来解决。但如果可能的话,我正在寻找一个更简单/优雅/干燥的解决方案;)
标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2 routes nested-routes