I was pretty eager to utilize this gem, but have run into a snag.
# User.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
has_many :wikis
# has_many :wikis, through: :collaborators
has_many :collaborators
has_many :collaborated_wikis, through: :collaborators, source: :wiki
after_initialize :init
def init
self.role ||= 'standard'
end
def admin?
role == 'admin'
end
def premium?
role == 'premium'
end
def standard?
role == 'standard'
end
def publicize_wikis
self.wikis.each { |wiki|
wiki.update_attributes(private: false)
wiki.collaborators.delete_all
}
end
end
# Wiki.rb
class Wiki < ActiveRecord::Base
belongs_to :user
has_many :collaborators
has_many :users, through: :collaborators
has_paper_trail :only => [:title, :body]
has_permalink
after_initialize :init
def init
self.private = false if self.private.nil?
end
def candidates
User.where.not(id: self.users).where.not(id: self.user).where.not(role: 'admin')
end
scope :public_wikis, -> { where(private: false) }
end
# Collaborator.rb
class Collaborator < ActiveRecord::Base
belongs_to :user
belongs_to :wiki
end
# wiki_policy.rb
class WikiPolicy < ApplicationPolicy
def index?
true
end
def show?
super && ( (!record.private) || (record.user == user || user.in?(record.users)) || (user.present? && user.admin?) )
end
def edit?
show?
end
def destroy?
user.present? && (record.user == user || user.admin?)
end
def private?
user.present? && ((user.premium? && (record.user == user || record.new_record?)) || user.admin?)
end
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
wikis = []
if user.present? && user.admin?
wikis = scope.all
elsif user.present? && user.premium?
# Here lies the issue - Incompatible relations
wikis = scope.public_wikis.or(user.wikis).or(user.collaborated_wikis)
else
wikis = scope.public_wikis
end
wikis
end
end
end
So User has_many wikis that they own, and has_many collaborated wikis through collaborator. Wiki's has many users through collaborator. When I try:
wikis = scope.public_wikis.or(user.wikis).or(user.collaborated_wikis)
I get an error from user.collaborated_wikis, which should return the relation of wikis related to this user. user.wikis works the same, by providing the wikis owned by user through collaborators. If I take out the collaborated_wikis call, even though scope.public_wikis and user.wikis are of different classes (ActiveRecord_Relation vs ActiveRecord_Associations_CollectionProxy, respectively) they play well together. If you look at the class of user.collaborated_wikis, it is that of ActiveRecord_Associations_CollectionProxy. Going into the rails console, I can see that the result of user.collaborated_wikis is a list of all the wikis that the user collaborates on, so I know the HMT relation works, I just can't figure out why the gem is saying that the structures are incompatible. Any ideas?