1

我正在通过学​​校的购买/转售平台项目开始使用 Ruby On Rails。当我尝试从关系模型中翻译模型时,我遇到了问题。

首先,我对我的数据库进行了建模。这里简化了实体关系模型:

实体关系模型

然后我将它翻译成关系模型:

关系模型

最后,我在 Ruby On Rails 中实现了它。

  • 我已经实现了一个模型 Client :

    class Client < ApplicationRecord
        attr_accessor :name
    
        validates :name, :presence => true
    
        has_many :purchasings, :dependent => :destroy
    
        has_many :sellers, :through => :purchasings
        has_many :articles, :through => :purchasings
    end
    
  • 我已经实现了一个模型 Seller :

    class Seller < ApplicationRecord
        attr_accessor :name
    
        validates :name, :presence => true
    
        has_many :purchasings, :dependent => :destroy
    
        has_many :sellers, :through => :purchasings
        has_many :articles, :through => :purchasings
    end
    
  • 我已经实现了一个模型文章

    class Article < ApplicationRecord
        attr_accessor :quantity
    
        validates :quantity, :presence => true
    
        has_one :purchasing, :dependent => :destroy
    
        has_one :client, :through => :purchasings
        has_one :seller, :through => :purchasings
    end
    
  • 我已经实现了一个模型 Purchasing :

    class Purchasing < ApplicationRecord
        attr_accessor :client_id, :seller_id, :article_id
    
        belongs_to :client, :class_name => "Client"
        belongs_to :seller, :class_name => "Seller"
        belongs_to :article, :class_name => "Article"
    
        validates :client_id, :presence => true
        validates :seller_id, :presence => true
        validates :article_id, :presence => true
    end
    
  • 我修改了采购数据库迁移:

    class CreatePurchasing < ActiveRecord::Migration[5.1]
        def change
            [...]
    
            add_index :purchasings, :client_id
            add_index :purchasings, :seller_id
            add_index :purchasings, :article_id
            add_index :purchasings, [:client_id, :seller_id], :unique => true
        end
    
        def down
            [...]
        end
    end
    

我知道这是不正确的,因为当我在 Rails 控制台上执行以下代码时:

cl1 = Client.create(:name => "John")
cl2 = Client.create(:name => "James")
sel1 = Seller.create(:nom => "Jack")
sel2 = Seller.create(:nom => "Jil")
a1 = Article.create(:quantity => 5)

p1 = Purchasing.new(:client => cl1, :client_id => cl1.id, :seller => sel1, :seller_id => sel1.id, :article => a1, :article_id => a1.id)
p1.save
p2 = Purchasing.new(:client => cl2, :client_id => cl2.id, :seller => sel1, :seller_id => sel1.id, :article => a1, :article_id => a1.id)
p2.save

p2.save返回真,而文章不能由同一个卖家出售并由两个不同的客户购买。

4

1 回答 1

1

您在采购表的不正确列上添加索引。根据要求,article_id 和 Seller_id 最好不要重复。所以你实际上需要的是对seller_id 和article_id 列的唯一性约束。您可以通过在数据库层上的两列seller_id 和文章id 的组合上创建唯一索引来实现。您还应该在购买模型上添加应用层验证。

class Purchasing < ApplicationRecord
attr_accessor :client_id, :seller_id, :article_id

belongs_to :client, :class_name => "Client"
belongs_to :seller, :class_name => "Seller"
belongs_to :article, :class_name => "Article"

validates :client_id, :presence => true
validates :seller_id, :presence => true
validates :article_id, :presence => true

validates :article_id, uniqueness: {scope: :seller_id}
end

现在您还应该编写一个数据库迁移以在这两列上添加唯一索引。

    class AddUniquenessConstraintInPurshasing < ActiveRecord::Migration
       def change
         add_index :purchasings, [:article_id, :seller_id], :unique => true
    end

结尾

于 2017-12-14T08:44:29.607 回答