I am working on rails 7 with 2 models which are Partner
and Package
, and I would like to assign the packages to the partner, but they need to be assigned together with their orders.
For example, if I assign package#A and package#B to the partner with 1st and 2nd order respectively, then package#A will be considered as a small package and package#B will be considered as a medium package.
So, I have created PartnerPackage
to link them together (with has_many through:
) and also added package_order
column to contain the package's order.
Question
What is the best way to retrieve all of the packages that belong to a specific partner, and also package_order
as well? Thank you so much for your answer!
Partner.rb
class Partner < ApplicationRecord
has_many :partner_packages, dependent: :destroy
has_many :packages, through: :partner_packages
end
Package.rb
class Package < ApplicationRecord
has_many :partner_packages, dependent: :destroy
has_many :packages, through: :partner_packages
end
PartnerPackage.rb
class PartnerPackage < ApplicationRecord
belongs_to :partner
belongs_to :package
validates :package_order, presence: true
end
CodePudding user response:
There's a virtually hidden feature of Rails that allows you to add any other columns to an SQL select and Rails makes them available as readonly attributes in the resulting object, eg:
[24] pry(main)> ff = Foo.select("*, current_timestamp as now").first
Foo Load (0.3ms) SELECT *, current_timestamp as now FROM "foos" ORDER BY "foos"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<Foo:0x0000000106442580 id: 1, name: "First Foo", age: 1, created_at: Thu, 21 Jul 2022 00:13:26.758228000 UTC 00:00, updated_at: Thu, 11 Aug 2022 15:23:14.015000000 UTC 00:00>
[25] pry(main)> ff.now
=> "2022-08-18 16:40:25"
So then you can use this to pull out the fields in a hmt table because you know that the SQL will include a join on that table:
partner.packages.select("packages.*, partner_packages.package_order")
Now if you want to get fancy you can use Arel
to avoid the string table names, but that's the basic idea.