Rails 5 – 使用编辑操作中的范围来查找特定实例的相关子项

我正在尝试学习如何在我的Rails 5应用程序中使用范围。

我在这里问了一个背景问题。

在我的Rails 5应用程序中有用户,提案和潜力的模型。

用户创建提案,然后他们自己和其他人可以创建评论。

模型之间的关联是:

用户

has_many :proposals, dependent: :destroy has_many :potentials 

提案

 belongs_to :user has_many :potentials, inverse_of: :proposal accepts_nested_attributes_for :potentials, reject_if: :all_blank, allow_destroy: true 

潜在

 belongs_to :proposal, inverse_of: :potentials belongs_to :user 

在我的路线文件中,我有两个潜在的资源。 我不确定我是否已经离开了滑雪道 – 我无法找到一个如何做到这一点的例子。 我有两个:

 resources :potentials 

以及:

 resources :proposals do resources :potentials 

目的:

当提出提案的用户尝试编辑它时,我只希望该用户能够编辑他们自己创建的潜力。

我为潜力设置了两条路线的原因是嵌套资源在提案表单中有一个嵌套的表单字段,因此提案创建者可以通过这种方式获得潜力。 任何其他看到提案并具有潜力的用户都可以通过单独的表单来完成。

任何用户(包括提案创建者,都可以通过单独的表单编辑潜力),提案创建者也可以通过提案表单中的嵌套表单编辑自己的任何提案。

目前,每当我编辑提案表单时(即使我不编辑潜在的嵌套字段),所有潜力都会更新,以插入提案创建者的用户ID,覆盖实际的潜在创建者的用户ID。

我正在尝试限制投标控制器中的编辑操作,以便它只允许在具有user_id == proposal.user_id的情况下编辑投标/潜力。

为此,我在我的提案中写了范围.rb

 scope :owner_potentials, ->{ where(user_id: potential.user_id ) } scope :third_party_potentials, ->{ where(user_id: != potential.user_id) } 

上面我喜欢的post中的解决方案是尝试使用范围。 由于范围是为了在类而不是实例上工作,我不得不试图弄清楚如何调整它们以便我可以使用范围来搜索所有符合要求的电位(即潜在的电位.user_id = = proposal.user_id)。 这意味着我没有搜索提案类,我正在搜索具体的提案。

这篇文章建议在相关的控制器动作中定义Event.all,但那么我将如何限制它,以便它只应用于特定的潜在编辑行? 我的编辑操作中还有其他行,不应在Proposal表上进行测试,而只是在实例上进行测试。 如果能够工作,我想我需要重写我的范围,试图排除所有其他提议。

有没有办法在具有范围的控制器中使用特定实例上的编辑操作?

我会建议像这样的范围:

 scope :owner_potentials, -> (user_id) { where(user_id: user_id) } scope :third_party_potentials, -> (user_id) { where.not(user_id: user_id) } 

调用这些范围时,您只需要传递当前用户的ID。

范围定义了它们所定义的AR类的查询您说您在proposal.rb中编写了owner_potentialsthird_party_potentials范围。 但是,如果这些范围旨在返回潜在的集合,则应在Potential类中定义这些范围。 如果需要从提议记录中访问这些范围,可以将范围链接到关联,例如

 class Potential scope :owner_potentials, -> (user) { where(user: user) } scope :third_party_potentials, -> (user) { where.not(user: user) } end ... class ProposalsController # Proposals::PotentialsController..? imo Proposals::PotentialsController#edit sounds like an endpoint for editing exactly one potential record and nothing else, which doesn't sound like what you want. Your call on how to structure the controller/routes though. def edit @proposal = ... # Whatever your logic is to find the proposal @proposal.potentials.owner_potentials(current_user) # do something with the user's potentials @proposal.potentials.third_party_potentials(current_user) # do something with the potentials the user doesn't own end end 

您可以在此处看到如何将关联(.potentials)链接到范围(.owner_potentials)。

此外,如果您有关联,则可以将该关联视为where方法中的字段,la where(user: user)而不是where(user_id: user.id)

最后要注意的是,您可能希望使用此重构更改范围的名称。 potentials.owner_potentials(user)有点多余。 也许像potentials.owned_by(user)