I have the following schema:
I want to have the option to call proposals
for both foreign_keys (author_id
and editor_id
) as well for separate ones (for example author_proposals
and editor_proposals
) and I need to have the option to lazy or eager load them (for example User.includes(:proposals)
or without it with joins
).
Update:
#I have the scopes which is like this:
class User < ActiveRecord::Base
has_many :author_proposals, class_name: 'Proposal', foreign_key: :author_id
has_many :editor_proposals, class_name: 'Proposal', foreign_key: :editor_id
end
class Proposal < ActiveRecord::Base
belongs_to :author, class_name: 'User', foreign_key: :author_id
belongs_to :editor, class_name: 'User', foreign_key: :editor_id
end
But I need a universal one which it will give me all the proposals (both author_proposals
and editor_proposals
) which it will also eager load them. Should I use conditions on has_many
?
I would do something like this:
class User < ActiveRecord::Base
has_many :authored_proposals, class_name: 'Proposal', foreign_key: :author_id
has_many :editored_proposals, class_name: 'Proposal', foreign_key: :editor_id
def proposals
Proposal.where('author_id = :id OR editor_id = :id', { id: id }).distinct
end
end
class Proposal < ActiveRecord::Base
belongs_to :author, class_name: 'User', foreign_key: :author_id
belongs_to :editor, class_name: 'User', foreign_key: :editor_id
def users
User.where(id: [author_id, editor_id].uniq)
end
end
You can do something like:
class User < ActiveRecord::Base
has_many :authored_proposals, class_name: 'Proposal', foreign_key: :author_id
has_many :editored_proposals, class_name: 'Proposal', foreign_key: :editor_id
def proposals
authored_proposals | editored_proposals
end
end
class Proposal < ActiveRecord::Base
belongs_to :author, class_name: 'User', foreign_key: :author_id
belongs_to :editor, class_name: 'User', foreign_key: :editor_id
def users
author | editor
end
end
You can eager load proposals
by doing: User.includes(:authored_proposals, :editored_proposals)
. This is not pure rails way, but seems cleaner to me.
You can also do :
class User < ActiveRecord::Base
has_many :authored_proposals, class_name: 'Proposal', foreign_key: :author_id
has_many :editored_proposals, class_name: 'Proposal', foreign_key: :editor_id
has_many : proposals, finder_sql: proc { "SELECT * FROM proposals WHERE (proposals.author_id = #{id} or proposals. editor_id = #{id})" }
end
Set your associations like this:
class User < ActiveRecord::Base
has_many :author_proposals, :class_name => "Proposal", :foreign_key => "author_id"
has_many :editor_proposals, :class_name => "Proposal", :foreign_key => "editor_id"
end
class Proposal < ActiveRecord::Base
belongs_to :author, :class_name => 'User', :foreign_key => "author_id"
belongs_to :editor, :class_name => 'User', :foreign_key => "editor_id"
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With