Как сделать эту модель ассоциации в FactoryGirl? - PullRequest
0 голосов
/ 26 февраля 2012

У меня есть эта модель рельсов (has_many: through)

class User < ActiveRecord::Base
  has_many :assignments
  has_many :roles, :through => :assignments  
end

class Assignment < ActiveRecord::Base
  belongs_to :user
  belongs_to :role
end

class Role < ActiveRecord::Base
  has_many :assignments
  has_many :users, :through => :assignments
end

В моем приложении только 3 роли (на данный момент), каждая роль: имя уникально. Таким образом, база данных ролей содержит 3 записи: пользователь, администратор, модератор.

Как я могу создать фабрики, чтобы я мог создавать пользователей, администраторов и модераторов и их роли?

Я бы хотел сделать что-то вроде:

(роль: имя проверяется на уникальность, поэтому он не должен создавать 1 запись роли на пользователя, вместо этого он должен создавать 1 назначение роли на пользователя.)

# Create my roles
FactoryGirl.create(:role, :name => 'admin')  
FactoryGirl.create(:role, :name => 'user')
FactoryGirl.create(:role, :name => 'moderator')

# Create 10 users and 10 moderators assuming that the username is sequential or something
for i in 0..10
    user = FactoryGirl.create(:user) # user.roles.first.name.eql? 'user' #should be true
    mod = FactoryGirl.create(:moderator)  # mod.roles.first.name.eql? 'moderator' #should be true
end

Как бы вы создали фабрики для моделирования этой ассоциации с FactoryGirl?

Ответы [ 3 ]

2 голосов
/ 27 февраля 2012

Я связался с Джошем Клейтоном (сопровождающим Factory Girl) по поводу этой проблемы, он любезно ответил на следующее:

Ограничение уникальности - это то, к чему это приведет, к сожалению, вам придется создавать роли вне цикла, присваивать им имена и повторно использовать эти имена. Могут быть и другие способы взломать его, но я не совсем уверен, если и как вы это сделаете.

Итак, в конце концов я решил проблему, выполнив что-то вроде:

     user_role = FactoryGirl.create(:role, :title => 'user')

     for i in (1..10) do
       user = FactoryGirl.create(:user)
       user.roles << user_role 
     end

Только что забыл про промежуточную таблицу «назначение».

0 голосов
/ 27 февраля 2012

используйте :class и :parent опции для определения фабрики.

Factory.define :user, :class => User do |u|
  u.role 'user'
end

Factory.define :moderator, :parent => :user do |m|
  m.role 'modelrator'
end

Так в ваших спецификациях:

  10.times{ Factory :user}
  9000.times{ Factory :moderator}
0 голосов
/ 27 февраля 2012
FactoryGirl.define do
  factory :user do
    col1 { Forgery(basic).col1_datatype }
  end
  factory :role do
    another_attribute { Forgery(basic).another_attr_datatype }
  end
  factory :assignment do
    user
    role
  end
end

Пара вещей

  1. Убедитесь, что в блоки пользователя и роли добавлены все столбцы, которые помогают удовлетворить проверки.
  2. То же самое относится к блоку назначения, если у вас есть какие-либо атрибуты не внешнего ключа.

В ваших тестах вы можете пойти двумя путями. * * 1010

Способ 1 (авто-магия)

@assign = FactoryGirl.create(:assign)

Способ 2 (более жесткий контроль)

@user = FactoryGirl.create(:user)
@role = FactoryGirl.create(:role)
@assign = FactoryGirl.create(:assign, user: @user, role: @role)

Тогда всегда есть документы.

...