Problem
I’m working on an application where I have a Company
model setup as follows:
class Company < ActiveRecord::Base
has_many :employee_roles
has_many :employees
validates :company_name, uniqueness: true
serialize :contractors, Array
end
Contractors
is related to the company as a serialized array and saves the data in the db as ["2", "1"]
where 2
and 1
are the id’s of the contractors
.
My code to extract the list of selected contractors
from this is:
def coach_list
@contractors = Contractor.where({ verified: true,
validated: true })
.where('membership_type != ?', Contractor.membership_types["no_membership"])
@company = Company.find(contractor_company_params[:company_id])
@selected_contractors = @company.contractors.map { |c| Contractor.find(c.to_i) }
@unselected_contractors = @contractors - @selected_contractors
end
I’m not sure if this is the best way to extracted @selected_contractors
and @unselected_contractors
Solution
If your database supports array types natively I would use that feature, I know that Postgres does. I would also call the field contractor_ids
or even selected_contractor_ids
then use a method called contractors
or selected_contractors
to return the actual objects.
I would change this:
@contractors = Contractor.where({ verified: true, validated: true })
.where('membership_type != ?', Contractor.membership_types["no_membership"])
to a scope or scopes on the Contractor
class. You can also code the second where
clause as where.not(membership_type: Contractor.membership_types["no_membership"])
And I would change this:
@selected_contractors = @company.contractors.map { |c| Contractor.find(c.to_i) }
to be a method on the Company
class. I would also write it as:
@selected_contractors = Contractor.find(@company.contractors)
this would issue a single query instead of n
queries, additionally the to_i
is not usually necessary.