Bijan Hoomand
Bijan Hoomand

Reputation: 191

Factory for database view in factory_girl

I am using Rails 5.0.2 with factory_girl_rails and RSpec.

I have 3 associative models like this:

/app/models/ticket.rb

class Ticket < ActiveRecord::Base
  has_many :ticket_snapshots, foreign_key: "duckduck_ticket_id"
end

/app/models/ticket_snapshot.rb

class TicketSnapshot < ActiveRecord::Base
  belongs_to :duckduck_ticket, class_name: "Ticket"
  has_many :matched_issues_summary,    class_name: "CookbookReportSummaryVw", foreign_key: "duckduck_ticket_snapshot_id"
end

/app/models/cookbook_report_summary_vw.rb

class CookbookReportSummaryVw < ActiveRecord::Base
  self.table_name = 'cookbook_report_summary_vw'
  belongs_to :duckduck_ticket_snapshot, class_name: "TicketSnapshot"
  belongs_to :duckduck_cookbook, class_name: "Cookbook"
end

As you can see, cookbook_report_summary_vw is not really a database table, but it's rather a database view (which works perfectly fine in the app, but it seems factory_girl doesn't like it too much, I'll show you the error later)

Here are my factory_girl factories for the above models:

factories/tickets.rb

FactoryGirl.define do

  factory :ticket do
    title 'ticket'
    ticket_id '11111111'

    factory :ticket2 do
      title 'something bad happened'
      issue 'unknown'
      requester 'duckie_duck'
      after(:create) do |ticket|
            ticket.ticket_snapshots << create(:TicketSnapshot, duckduck_ticket: ticket)
      end
    end
  end
end

factories/ticketsnapshots.rb

FactoryGirl.define do

  factory :TicketSnapshot do

    association :duckduck_ticket

    factory :snapshot1 do
      status 'Pending'
      closure_code nil
      root_cause 'other'
      after(:create) do |ts|
        ts.matched_issues_summary << create(:CookbookReportSummaryVw, duckduck_ticket_snapshot: ts)
      end
    end

  end
end

factories/cookbook_report_summary_view.rb

FactoryGirl.define do
  factory :CookbookReportSummaryVw do

    association :duckduck_ticket_snapshot

    factory :summary_true do
      status 'true'

    end

  end
end

In my factories, I have defined that a ticket can have many ticket_snapshots and each ticket_snapshot can have many cookbook_report_summary.

In RSPec, if I only try to create a ticket, I do not get any error (well, if I remove the after(:create) in factories/tickets.rb); however with that line in there, I can never get a snapshot created and I get this error:

ActiveRecord::StatementInvalid:
  PG::UndefinedTable: ERROR:  relation "cookbook_report_summary_vw" does not exist
  LINE 8:                WHERE a.attrelid = '"cookbook_report_summary_...
      SELECT a.attname, format_type(a.atttypid, a.atttypmod),
           pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
      (SELECT c.collname FROM pg_collation c, pg_type t

I am not sure if I didn't define my associations correctly, or factory_girl cannot interact with PostgreSQL view.

I found a solution for factory_girl interacting with database views, but I cannot quite understand how to change my cookbook_report_summary_vw to adhere to that: https://github.com/thoughtbot/factory_bot/issues/449

After a full day of working on this, I thought let's ask for your expert views. I should say that I don't necessarily need to use factory_girl if there are better alternatives out there for my use case as well.

Any help is greatly appreciated.

Upvotes: 2

Views: 617

Answers (1)

Bijan Hoomand
Bijan Hoomand

Reputation: 191

Answering for the sake of closure, as Josh mentioned, my test environment migrations were not up to date and factory girl was quite innocent!

Upvotes: 0

Related Questions