Остановить FactoryGirl, преобразующую мои строки в числа с плавающей запятой

У меня есть эти фабрики:

FactoryGirl.define do
        factory :product do
                name { Faker::Commerce.product_name }
                price { Faker::Commerce.price }
                image { Faker::Internet.url }
        end

        factory :new_product, parent: :product do
                name nil
                price nil
                image nil
        end

        factory :string_product, parent: :product do
                price { Faker::Commerce.price.to_s }
        end
end

Почему я хочу использовать :string_product? Ну, хотя атрибут цены имеет тип данных float на уровне базы данных, иногда я хочу построить фабрику со всеми атрибутами в виде строк.

Это делается для того, чтобы я мог построить фабрику, а затем запускать ожидания относительно ее атрибутов, когда они передаются в хеш параметров. (Все параметры из URL являются строками)

Однако в консоли рельсов:

> FactoryGirl.build :string_product
=> #<Product:0x00000007279780 id: nil, name: "Sleek Plastic Hat", price: 43.54, image: "http://blick.name/moie", created_at: nil, updated_at: nil>

Как видите, price все еще сохраняется как строка.

Эксперимент, чтобы попытаться увидеть, что происходит:

        ...
        factory :string_product, parent: :product do
                price { "WHY ARE YOU NOT A STRING?" }
        end
        ...

приводит к:

=> #<Product:0x000000077ddfa0 id: nil, name: "Awesome Steel Pants", price: 0.0, image: "http://rogahn.com/kavon", created_at: nil, updated_at: nil>

Моя строка теперь преобразована в число с плавающей запятой 0.0

Как предотвратить такое поведение? Если я хочу, чтобы один из моих атрибутов был строкой, особенно когда я только build использую его, мне должно быть разрешено. Есть ли конфигурация FactoryGirl, где я могу остановить это? То же самое происходит и с драгоценным камнем Fabrication, так что я предполагаю, что это как-то связано с моделью? Моя модель Product сейчас буквально пуста... никаких проверок или чего-то еще, так как же это может быть? Единственный способ, которым FactoryGirl знает, что цена — это число с плавающей запятой, заключается в том, что она имеет этот тип данных на уровне базы данных.

В любом случае, это действительно раздражает, если бы кто-нибудь мог показать мне, как разрешить мне записывать строки в атрибуты моей фабрики, я был бы очень признателен. Я мог бы использовать .to_s в самой спецификации, но я хочу, чтобы мои спецификации были максимально чистыми, и я подумал, что фабрики будут отличным местом для сохранения этой конфигурации...

Есть ли производственная библиотека, которая позволила бы мне это сделать?

Еще немного экспериментов:

> "WHY ARE YOU NOT A STRING".to_f
=> 0.0

Итак, где-то в рельсах или в factorygirl вызывается to_f на моей любимой строке. Где? И как мне это остановить?


person Starkers    schedule 26.06.2015    source источник
comment
Если вы хотите выполнить проверку входных параметров, вы должны сделать это в тесте контроллера. На уровне модели рельсы преобразуют ввод при назначении. Например. product.new.price = 'somestring' приведет к 0,0 для цены. Другими словами, в вашей модели у вас никогда не может быть строкового значения для столбца с плавающей запятой.   -  person AOG    schedule 26.06.2015
comment
Это не имеет ничего общего с фабричной девушкой. Столбец вашей базы данных определен как число с плавающей запятой, поэтому ActiveRecord автоматически преобразует его. Если вы хотите получить исходное значение, присвоенное данному атрибуту, используйте price_before_type_cast. Еще один момент: ваши фабрики всегда должны генерировать действительные модели - если вы хотите использовать их для целей проверочного тестирования, измените значения вручную в тесте.   -  person BroiSatse    schedule 26.06.2015
comment
@BroiSatse Почему ActiveRecord имеет какое-либо отношение к строящейся / создаваемой фабрике? Я думал, что идея в том, что вы можете использовать фабрики в моках, полностью изолированных от уровня модели. Возможно, mock_model rspec лучше, чем фикстуры/фабрики...   -  person Starkers    schedule 26.06.2015
comment
@Starrkers - FactoryGirl должна генерировать модели, а не заглушать их. Если вы хотите протестировать одну модель в полной изоляции от других моделей, используйте девушку-фабрику, чтобы сгенерировать ее и заглушить все ее ассоциации. (или только те, которые вы ожидаете использовать в тесте). Не могли бы вы обновить свой вопрос, указав настоящую проблему, с которой вы столкнулись, то есть чего вы пытаетесь достичь?   -  person BroiSatse    schedule 26.06.2015


Ответы (1)


С fabrication вам нужно использовать attributes_for для создания хеш-представления вашего объекта. Он полностью обходит модель ActiveRecord, поэтому ничего не нужно принуждать.

Fabricate.attributes_for(:string_product)

person Paul Elliott    schedule 26.06.2015