如何确保表不包含重复项(基于两个外键)?

时间:2016-04-14 21:00:29

标签: ruby-on-rails ruby associations rails-api

我有三种模式:

class Ingredient < ActiveRecord::Base
  has_one :component
end

class Size < ActiveRecord::Base
  has_one :component
end

class Component < ActiveRecord::Base
  belongs_to :ingredient
  belongs_to :size
end

我的schema.rb看起来像是:

ActiveRecord::Schema.define(version: 20160414202240) do

  create_table "components", force: :cascade do |t|
    t.boolean  "active"
    t.decimal  "cost"
    t.decimal  "price"
    t.datetime "created_at",    null: false
    t.datetime "updated_at",    null: false
    t.integer  "size_id"
    t.integer  "ingredient_id"
  end

  add_index "components", ["ingredient_id"], name: "index_components_on_ingredient_id"
  add_index "components", ["size_id"], name: "index_components_on_size_id"

  create_table "ingredients", force: :cascade do |t|
    t.string   "name"
    t.boolean  "active"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "sizes", force: :cascade do |t|
    t.string   "name"
    t.boolean  "active"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

end

现在,我正在使用以下方式播种数据库:

size_small = Size.create(name: 'Small', active: true)
size_medium = Size.create(name: 'Medium', active: true)
size_large = Size.create(name: 'Large', active: true)

ingredient_tomato = Ingredient.create(name: 'Tomato', active: true)
ingredient_onion = Ingredient.create(name: 'Onion', active: true)
ingredient_red_onion = Ingredient.create(name: 'Red onion', active: true)
ingredient_champignons = Ingredient.create(name: 'Champignons', active: true)
ingredient_shrimps = Ingredient.create(name: 'Shrimps', active: true)

Component.create(cost: 0.20, price: 1.00, active: true, size: size_small, ingredient: ingredient_tomato)
Component.create(cost: 0.20, price: 1.00, active: true, size: size_small, ingredient: ingredient_onion)
Component.create(cost: 0.20, price: 1.00, active: true, size: size_small, ingredient: ingredient_red_onion)
Component.create(cost: 0.30, price: 1.00, active: true, size: size_small, ingredient: ingredient_champignons)
Component.create(cost: 0.50, price: 1.50, active: true, size: size_small, ingredient: ingredient_shrimps)

Component.create(cost: 0.30, price: 1.50, active: true, size: size_medium, ingredient: ingredient_tomato)
Component.create(cost: 0.30, price: 1.50, active: true, size: size_medium, ingredient: ingredient_onion)
Component.create(cost: 0.30, price: 1.50, active: true, size: size_medium, ingredient: ingredient_red_onion)
Component.create(cost: 0.45, price: 1.50, active: true, size: size_medium, ingredient: ingredient_champignons)
Component.create(cost: 0.75, price: 2.25, active: true, size: size_medium, ingredient: ingredient_shrimps)

Component.create(cost: 0.40, price: 2.00, active: true, size: size_large, ingredient: ingredient_tomato)
Component.create(cost: 0.40, price: 2.00, active: true, size: size_large, ingredient: ingredient_onion)
Component.create(cost: 0.40, price: 2.00, active: true, size: size_large, ingredient: ingredient_red_onion)
Component.create(cost: 0.60, price: 2.00, active: true, size: size_large, ingredient: ingredient_champignons)
Component.create(cost: 1.00, price: 3.00, active: true, size: size_large, ingredient: ingredient_shrimps)

# This one uses again `size_small` and `ingredient_tomato` and shouldn't be allowed.
Component.create(cost: 2.99, price: 7.99, active: true, size: size_small, ingredient: ingredient_tomato)

验证最多rails-api方式的是什么,sizeingredient组合在一起应该在Component表中唯一?

我应该在Component的控制器中实现某些逻辑,还是可以设置一些规则/范围/什么?

请原谅我的无知,我刚开始学习Ruby(和Rails)。

我将Rails 4.2.6Ruby 2.3.0p0 (2015-12-25 revision 53290)一起使用。

提前致谢。

1 个答案:

答案 0 :(得分:2)

您需要向模型添加范围唯一性验证,并为组件表添加唯一索引。

 #import "Test.h"

 @implementation Test


 -(void)testMethod{
     NSLog(@"test");
 }

 @end

添加唯一索引的原因是为了确保多线程服务器的唯一性。这篇文章中你可以通过Rails http://www.kpheasey.com/2016/02/09/thread-safe-model-uniqueness-validations/

阅读有关线程安全唯一性验证的更多信息