Перевод моделей баз данных в модели на Ruby On Rails

Я начинаю Ruby On Rails через проект платформы покупки / перепродажи в школе. У меня проблема с моими моделями, когда я пытаюсь перевести их из моей реляционной модели.

Во-первых, я смоделировал свою базу данных. Вот упрощенная модель сущности-отношения:

Модель сущности-отношения

Затем я перевел это в реляционную модель:

Реляционная модель

Наконец, я реализовал это в Ruby On Rails.

  • Я реализовал модель клиента:

    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
    
  • Я реализовал модель продавца:

    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
    
  • Я реализовал модель закупок:

    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 возвращает true, тогда как товар не может быть продан одним и тем же продавцом и куплен двумя разными клиентами.

1 ответ

Решение

Вы добавляете индекс по неверным столбцам в таблице покупок. Согласно требованию, article_id и seller_id не должны повторяться в идеале. Таким образом, вам действительно нужно ограничение уникальности для seller_id и столбца article_id. Это можно сделать, создав уникальный индекс по составу двух столбцов seller_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

конец

Другие вопросы по тегам