-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Access to constructor attributes hash within dynamic attribute block? + nested association #583
Comments
What you're looking for are transient attributes. Best of luck! |
I'm aware of the transient attributes, however, in my case, I don't want the user of the factory to have to remember to use the transient attribute. No 'evaluator' I could tap in the block? |
@gamov can you provide the real example? I'm not sure changing quantity like that is actually ideal because it introduces a level of indirection (if you set a value, I'd assume that value be the value assigned and not change). |
First of all, thanks for your help. I switched around the requirement and it leads to cleaner factories and only broke a few tests which were easily fixed. Now quantity of the nested association is always valid. class ShippingItem < ActiveRecord::Base
belongs_to :purchased_item
validate { errors.add(:quantity, "cannot be higher than available quantity: #{purchased_item.quantity}") if purchased_item.quantity < quantity }
end Shipping Item factory: factory :shipping_item do
quantity { rand 3..100 }
purchased_item {association :purchased_item, quantity: (quantity..(quantity + 100)).to_a.sample}
end This works fine if you set the quantity or not when invoking the shipping item factory (which was my original question). factory :shipping_item do
quantity { rand 3..100 }
ignore {delivery_site nil}
purchased_item {association :purchased_item,
quantity: (quantity..(quantity + 100)).to_a.sample,
delivery_site: (delivery_site || FactoryGirl.build :delivery_site)
}
end However, I can see it becoming a pattern and doesn't feel 'right' or DRY. Is it the usual way? |
@gamov okay, this is starting to make more sense now, and yes, I agree this isn't DRY. In cases like this (especially because this is likely a simple case and there are MUCH more complicated ones out there), I actually create support classes for building complicated data (either because there's a LOT of associated data or certain aspects change and it impacts creation of other factories, like this). The example I point to in cases like this is here: #230 (comment) At the end of the day, factory_girl can't (and won't!) handle every permutation of every way objects get associated and built. It's just not possible. In cases like yours where there's little things that change, I always recommend solving things with pure Ruby. It's flexible, extensible, and technically testable if you want. Hopefully this helps - I know "factory_girl can't handle this well" doesn't sound ideal, but it really is, since it keeps factory_girl's interface clean and understandable and removes the chance for odd edge cases. |
I still wish we could access the constructor supplied hash to check what has been supplied to make some choice in the lazy attribute block… |
I tried asking this twice in the Google Group but both time my post disappeared…:
I would like to do different things if a certain attribute is passed to the constructor or not (using default), e.g.:
so the quantity will have different value if I specify the quantity or not in the constructor:
Is this possible?
PS: In the getting started document, I think it would be good to specify that association attributes are processed before other attributes even though they could be defined after them in the define block.
The text was updated successfully, but these errors were encountered: