1

我正在重构我的应用程序以在任何地方使用 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_nodesanchor_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,因为这不是数据库的设计方式。

4

1 回答 1

1

1:当 rails 传入测量 id 时,您的 ExperimentsController#show 操作可能正在寻找 params[:id] 来查找实验。您将需要执行以下操作:

@experiment = Experiment.find(params[:measurement_id])

但是,这不起作用,因为您的实验表没有 measure_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

在您的物理节点控制器中创建一个 show_tag 和 show_anchor 操作。然后这些操作将查找 params[:measurement_id)

于 2013-03-01T20:01:49.010 回答