【问题标题】:How to set up associations for accepting one proposal in Rails?如何在 Rails 中建立接受一个提案的协会?
【发布时间】:2020-08-26 19:29:29
【问题描述】:

我正在 Rails 应用程序中开发一项功能,该功能允许 users 创建 projects。然后,其他用户可以创建proposals。最后,创建项目的用户可以接受其中一个提案作为已接受的提案。

让创建项目的用户(经理)选择其中一个提案作为接受提案的最佳方式是什么?

模型是这样设置的:

用户模型

class User < ApplicationRecord
  has_many :projects
  has_many :proposals
end

项目模型

class Project < ApplicationRecord
  belongs_to :manager, class_name: 'User', foreign_key: :user_id
  has_many :proposals
end

提案模型

class Proposal < ApplicationRecord
  belongs_to :project
  belongs_to :user
end

起初,我想到了提案表中的“已接受”布尔值,它允许用户将布尔值标记为真以使提案“被接受”。但这可能会导致一些问题,例如某些项目有多个被接受的提案。这不是正确的做法。

那么,我应该如何设置一个接受模型,允许经理选择和取消选择一个提案作为唯一的“接受”提案?

【问题讨论】:

    标签: ruby-on-rails activerecord associations


    【解决方案1】:

    如果您想 100% 确定没有一个项目可以有多个已接受的提案,那么您可以使用附加关系对其进行设置。您还需要提案中的另一个关系

    class Project < ApplicationRecord
      belongs_to :accepted_proposal, class_name: 'Proposal', inverse_of: :accepted_for, optional: true
    end
    
    class Proposal < ApplicationRecord
      has_one :accepted_for, class_name: 'Project', inverse_of: :accepted_proposal
    end
    

    您也可以仅验证已接受提案的唯一性,但我认为您不能为此拥有数据库唯一索引

    class Proposal < ApplicationRecord
      validates :project_id, :uniqueness, if: Proc.new { |proposal| proposal.accepted }
    end
    

    【讨论】:

    • 此解决方案阻止用户(经理)创建新项目,因为它会寻找项目的接受提案,而它不会拥有。
    • 是的,你是对的,我总是忘记设置optional: true。我更新了答案。如果您使用的是旧版本的 rails (required: false
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多