I have these models in Rails 6.1.7:
class AdminUser < ApplicationRecord
belongs_to :anization, foreign_key: 'type_id'
end
class OrganizationUser < AdminUser
end
and defined in the file spec/fabricators/admin_user_fabricator.rb :
Fabricator(:admin_user) do
email { Fery(:internet).email_address }
first_name { Fery(:name).first_name }
last_name { Fery(:name).last_name }
end
Fabricator(:anization_user, from: :admin_user, class_name: :anization_user) do
anization
end
but when I try to fabricate the attributes in my Rspec test:
Fabricate.attributes_for(:anization_user)
I'm getting:
{"email"=>"[email protected]", "first_name"=>"Carolyn", "last_name"=>"Gutierrez", "anization_id"=>6919}
F
Failures:
ActiveModel::UnknownAttributeError:
unknown attribute 'anization_id' for OrganizationUser.
So, the attribute "anization_id" shouldn't be there. Besides, the attributes "type"=>"OrganizationUser" and "type_id"=>6939 should be there.
I don't haven experience with this gem yet. I tried several changes, but no luck so far. I don't know what I'm doing wrong.
I have these models in Rails 6.1.7:
class AdminUser < ApplicationRecord
belongs_to :anization, foreign_key: 'type_id'
end
class OrganizationUser < AdminUser
end
and defined in the file spec/fabricators/admin_user_fabricator.rb :
Fabricator(:admin_user) do
email { Fery(:internet).email_address }
first_name { Fery(:name).first_name }
last_name { Fery(:name).last_name }
end
Fabricator(:anization_user, from: :admin_user, class_name: :anization_user) do
anization
end
but when I try to fabricate the attributes in my Rspec test:
Fabricate.attributes_for(:anization_user)
I'm getting:
{"email"=>"[email protected]", "first_name"=>"Carolyn", "last_name"=>"Gutierrez", "anization_id"=>6919}
F
Failures:
ActiveModel::UnknownAttributeError:
unknown attribute 'anization_id' for OrganizationUser.
So, the attribute "anization_id" shouldn't be there. Besides, the attributes "type"=>"OrganizationUser" and "type_id"=>6939 should be there.
I don't haven experience with this gem yet. I tried several changes, but no luck so far. I don't know what I'm doing wrong.
Share Improve this question edited Jan 17 at 19:35 aarkerio asked Jan 17 at 19:05 aarkerioaarkerio 2,3742 gold badges22 silver badges38 bronze badges2 Answers
Reset to default 2There seems to be some confusion between your database tables structure, your models and the way Fabrication gem works.
The type
field
It looks like you're working with Single Table Inheritance, so it makes sense to expect your database table to contain the type
column. And you can verify that by running OrganizationUser.column_names
or AdminUser.column_names
. If STI was generated correctly, you should see the type
column listed there.
This column will be automatically set whenever you instantiate an object for the child class.
> OrganizationUser.new.type
=> "OrganizationUser"
And a similar result is expected if you build an OrganizationUser
object with fabrication:
> anization_user = Fabricate.build(:anization_user)
> anization_user.type
=> "OrganizationUser"
However, when you call Fabricate.attributes_for
, you're not instantiating a model object. attributes_for
only loads what's present in the definitions for your fabrications. That's why you don't see the type
field listed there. Your fabricators have no type
field. If you want it to be returned, you must explicitly add type "OrganizationUser"
to your anization_user
fabricator.
The anization_id
attribute and the type_id
column
The anization_id
attribute is returned when you call for Fabricate.attributes_for(:anization_user)
because you specified the association
relation in your fabricator. Similar to the topic above, note that attributes_for
will return a list according to your fabricator definitions. If an association is passed, it will try to generate an ID based on it (regardless of which foreign key you defined in your model).
I don't see much about Organization
in your question.
I'm assuming you also have an anizations
table and an Organization
model and that you added a type_id
column to the admin_users
table. You might want to go through those steps if any of these assumptions are incorrect. I'd suggest not using the type_id
name for that FK unless you have a strong reason for that choice. If you could stick to the conventional FK anization_id
, that can make your code easier to follow.
Fabricator suggestion
Assuming you're keeping type_id
as the FK, you could have something like the following:
Fabricator(:anization_user, from: :admin_user, class_name: :anization_user) do
type "OrganizationUser"
type_id { Fabricate(:anization).id }
end
And then you call it on your specs without the need for extra params:
attributes = Fabricate.attributes_for(:anization_user)
As Lidiane suggested, I fixed the issue with:
let(:user_attrs) { Fabricate.attributes_for(:anization_user, type: 'OrganizationUser', type_id: Fabricate(:anization).id).except(:anization_id) }
Yeah, ugly as heck, I know. Bad designed models.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745347580a4623631.html
评论列表(0条)