ruby on rails - foreign_key and Fabricator-gem? - Stack Overflow

I have these models in Rails 6.1.7:class AdminUser < ApplicationRecordbelongs_to :anization, foreig

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 badges
Add a comment  | 

2 Answers 2

Reset to default 2

There 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

相关推荐

  • ruby on rails - foreign_key and Fabricator-gem? - Stack Overflow

    I have these models in Rails 6.1.7:class AdminUser < ApplicationRecordbelongs_to :anization, foreig

    8小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信