factory :job_application
догадается, что вы хотите сделать объект класса JobApplication
. Чтобы сделать Hash
, вам нужно сделать это явно. См. Определение фабрик .
factory :job_application, class: Hash
Поскольку Hash.new
не принимает набор пар ключ / значение, вам необходимо переопределить поведение инициализации по умолчанию. Я нашел самое простое, что нужно сделать - вернуть attributes
фабрики. См. Пользовательская конструкция .
Они используют символьные ключи, вам нужны строковые ключи, поэтому мы используем deep_stringify_keys
. Это также заботится о клонировании attributes
на всякий случай.
factory :job_application, class: Hash do
initialize_with do
attributes.deep_stringify_keys
end
end
Теперь вы можете добавить атрибуты обычным способом.
factory :job_application, class: Hash do
email { "jorb@coachz.biz" }
initialize_with do
attributes.deep_stringify_keys
end
end
Поскольку нет метода save
, Вы можете только build
эти заводы Ha sh.
# Yes
jorb = FactoryBot.build(:job_application)
# No
jorb = FactoryBot.create(:job_application)
Я часто этим занимаюсь, поэтому я построил string_hash
фабрику для наследования.
factory :string_hash, class: Hash do
initialize_with do
attributes.deep_stringify_keys
end
end
factory :job_application, parent: :string_hash do
email { "jorb@coachz.biz" }
end
Если вы хотите использовать вложенные хэши, я предлагаю вам создать дополнительные фабрики и связать их вместе. Это позволяет вам легко изменять значения во вложенных хэшах.
Ассоциации по умолчанию используют create
, нам нужно явно build
наших ассоциаций. См. Ассоциации .
factory :address, parent: :string_hash do
street { "Ahead St." }
postal_code { "12345" }
end
factory :job_application, parent: :string_hash do
association :address, strategy: :build
email { "jorb@coachz.biz" }
name { "Coach Z" }
end
build(:job_application,
address: build(:address, street: "Sesame St.")
)
Спросите себя, имеет ли смысл определять их как модели . Это заставляет их работать с обычными фабриками и функциями, такими как проверка, и вы можете добавлять методы и все такое хорошее.
Поскольку эти данные вы получаете в контроллере, может быть полезно наличие проверок и методов. См. Объекты формы ActiveModel от ThoughtBot .
class JobApplication
include ActiveModel::Model
include ActiveModel::Validations
attr_accessor :email, :name, :address
validates :name, :email, presence: true
end
class Address
include ActiveModel::Model
attr_accessor :street, :postal_code
end
factory :address do
street { "Ahead St." }
postal_code { "12345" }
end
factory :job_application do
# Can't save a Model either.
association :address, strategy: :build
email { "jorb@coachz.biz" }
name { "Coach Z" }
end