Connecting database view with polymorphic model in

2019-06-08 02:42发布

问题:

I have the following setup which allows a user to have multiple projects and each project can have multiple tasks. A user can favourite multiple projects.

class User < ActiveRecord::Base
  has_many :projects
  has_many :tasks, :through => :projects
  has_many :favourites
  has_many :favourite_projects, :through =>  :favourites, :source => :favourable, :source_type => "Project"
  has_many :favourite_tasks, :through => :favourite_projects, :source => :tasks
  ...
end

class Project < ActiveRecord::Base
  belongs_to :user
  has_many :tasks
  has_many :favourites, :as => :favourable
  ...
end

class Task < ActiveRecord::Base
  belongs_to :project
  ...
end

class Favourite < ActiveRecord::Base
  belongs_to :user
  belongs_to :favourable, :polymorphic => true
  ...
end

This setup allows @user.favourite_tasks to list all the tasks for the projects that they have favourited.

Taking the suggestion from here (http://pivotallabs.com/database-views-performance-rails/) I am trying to replace the multi-level table joins with a database view where possible instead.

The view SQL is:

SELECT tasks.id AS task_id, ..., projects.id AS project_id, ... 
FROM tasks INNER JOIN projects ON projects.id = tasks.project_id

My new ProjectTask model is:

class ProjectTask < ActiveRecord::Base
  self.primary_key = 'task_id'
end

I've updated my User model to include:

has_many :project_tasks

which works fine for @user.project_tasks.

However, I can't figure out what the has_many/has_one/belongs_to should be in the models for the favourites to work (connecting the favourites to the view rather than the projects table).

I'm aiming for has _many :favourite_project_tasks, :through => :favourites.... so that I can use @user.favourite_project_tasks in my controller and attach any ProjectTask model scopes to it if need be. I think the fact that the ProjectTask model has task_id as the primary key is causing issue with rails linking the tables/view and because using :through overrides any use of :foreign_key and :primary_key (according to http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many).

Hopefully someone can advise what I should be doing because I've tried loads of combinations of changes with no joy.

Thanks

回答1:

Issue seems to have been caused by the custom primary key.

By updating the User model with (I was already doing this when it was failing):

has_many :favourite_project_tasks, :through => :favourite_projects, :source => :project_tasks

to use the view and also changing the view to use:

SELECT tasks.id AS id, ...

rather than:

SELECT tasks.id AS task_id, ...

and changing the ProjectTask view model to use:

self.primary_key = :id

it now works.