我正在重构我的应用程序,以便在任何地方使用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
什么有效:
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)
这应该很容易修复。更重要的是:
GET "/measurements/2/tag_node"
Processing by PhysicalNodesController#show as HTML
Parameters: {"measurement_id"=>"2"}
如何让我调用它来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
,因为这不是数据库的设计方式。
答案 0 :(得分:1)
1:您的ExperimentsController #show action可能会寻找params [:id]来查找rails在测量ID中传递的实验。您需要执行以下操作:
@experiment = Experiment.find(params[:measurement_id])
但是,由于您的实验表没有measurement_id列,因此无法使用。我不建议将实验嵌套作为测量资源。这不是您的数据库的布局方式。如果你仍然希望嵌套它,这就是你需要做的:
@experiment = Measurement.find(measurement.experiment_id).experiment
您的“has_many”和“belongs_to”不需要“foreign_key”属性。 Rails会自己解决这个问题。
2:由于此路由的父资源是Measurement,因此rails将假定调用id参数:measurement_id。像这样更新您的关联:
class Measurement < ActiveRecord::Base
self.table_name = 'measurement'
self.primary_key = 'id'
belongs_to :tag_node, :class_name => 'PhysicalNode', :foreign_key => :tag_node_id
belongs_to :anchor_node, :class_name => 'PhysicalNode', :foreign_key => :anchor_node_id
belongs_to :experiment
end
class PhysicalNode < ActiveRecord::Base
self.table_name = 'physical_node'
self.primary_key = 'id'
has_many :tag_node, :class_name => 'Measurement', :foreign_key => :tag_node_id
has_many :anchor_node, :class_name => 'Measurement', :foreign_key => :anchor_node_id
end
class Experiment < ActiveRecord::Base
self.table_name = 'experiment'
self.primary_key = 'id'
has_many :measurements
end
我不会在测量资源下嵌套任何内容,因为它是子资源,而不是父资源。由于您的/ measurements / 1 / [anythingelse]是测量路由,因此rails假定id为:measurement_id。 您在ID为1的测量资源/对象下嵌套。换句话说,您说测量x HAS tag_nodes和HAS anchor_nodes,这不是真的。
如果您仍然想要,可以在控制器中为每个资源创建单独的操作,如下所示:
resources :measurements, only: [:index, :show] do
resource :tag_node, controller: :physical_nodes, only: [:show_tag]
resource :anchor_node, controller: :physical_nodes, only: [:show_anchor]
resource :experiment, only: [:show]
end
在physical_nodes控制器中创建show_tag和show_anchor操作。然后,这些操作将查找params [:measurement_id)