class A < ActiveRecord::Base
has_many :ab_relationships
has_many :bs, through: :ab_relationships, source: :b
def self.create_with_ids b_ids
a = nil
A.transaction do
a = A.create
b_ids.each do |id|
b = B.find(id)
r = AbRelationship.create(a: a, b: b)
end
end
a.persisted? ? a : nil
end
end
class A < ActiveRecord::Base
has_many :ab_relationships
has_many :bs, through: :ab_relationships, source: :b
end
class B < ActiveRecord::Base
has_many :ab_relationships
has_many :as, through: :ab_relationships, source: :a
end
class AbRelationship < ActiveRecord::Base
belongs_to :a
belongs_to :b
validate :ololo_validator
private
def ololo_validator
if AbRelationship.where(a: self.a).first.present?
errors.add(:ab_relationships, "error")
end
end
end
2.2.2 :005 > B.create
(0.1ms) begin transaction
SQL (0.3ms) INSERT INTO "bs" ("created_at", "updated_at") VALUES (?, ?) [["created_at", "2015-10-10 08:46:40.136477"], ["updated_at", "2015-10-10 08:46:40.136477"]]
(1.7ms) commit transaction
=> #<B id: 2, created_at: "2015-10-10 08:46:40", updated_at: "2015-10-10 08:46:40">
2.2.2 :006 > a = A.create(b_ids: [B.first.id])
B Load (0.2ms) SELECT "bs".* FROM "bs" ORDER BY "bs"."id" ASC LIMIT 1
B Load (0.1ms) SELECT "bs".* FROM "bs" WHERE "bs"."id" = ? LIMIT 1 [["id", 1]]
(0.1ms) begin transaction
AbRelationship Load (0.1ms) SELECT "ab_relationships".* FROM "ab_relationships" WHERE "ab_relationships"."a_id" IS NULL ORDER BY "ab_relationships"."id" ASC LIMIT 1
SQL (0.3ms) INSERT INTO "as" ("created_at", "updated_at") VALUES (?, ?) [["created_at", "2015-10-10 08:46:58.276925"], ["updated_at", "2015-10-10 08:46:58.276925"]]
AbRelationship Load (0.1ms) SELECT "ab_relationships".* FROM "ab_relationships" WHERE "ab_relationships"."a_id" = 1 ORDER BY "ab_relationships"."id" ASC LIMIT 1
SQL (0.1ms) INSERT INTO "ab_relationships" ("b_id", "a_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["b_id", 1], ["a_id", 1], ["created_at", "2015-10-10 08:46:58.279207"], ["updated_at", "2015-10-10 08:46:58.279207"]]
AbRelationship Load (0.1ms) SELECT "ab_relationships".* FROM "ab_relationships" WHERE "ab_relationships"."a_id" = 1 ORDER BY "ab_relationships"."id" ASC LIMIT 1
(0.8ms) rollback transaction
=> #<A id: nil, created_at: "2015-10-10 08:46:58", updated_at: "2015-10-10 08:46:58">
2.2.2 :007 > a.valid?
AbRelationship Load (0.2ms) SELECT "ab_relationships".* FROM "ab_relationships" WHERE "ab_relationships"."a_id" IS NULL ORDER BY "ab_relationships"."id" ASC LIMIT 1
=> true
2.2.2 :008 > a.persisted?
=> false
2.2.2 :009 >
for attemps in 0..3
self.id = generate_id
return if Name.find_by(id: self.id).nil?
end
я тоже уменьшаю вероятность фак-апа, а вопрос в том как сделать что бы эта вероятность была нулевой.
транзакии? но как правильно это сделать?