Below is the model Structure.
class UserFamilyRole < ActiveRecord::Base
belongs_to :user_family
belongs_to :user_role
belongs_to :organization
end
class UserFamily < ActiveRecord::Base
has_many :user_family_roles
has_many :user_roles
end
I am looking for below result from the above UserFamilyRole table.
{
user_family1: [user_role1, user_role2],
user_family2: [user_role1, user_role2, user_role3]
...
}
I achieved this Result from below query:
user_family_roles = UserFamilyRole.where(:organization_id => org_id)
results = {}
juser_family_roles.each do |user_family_role|
user_family = UserFamily.find(user_family_role.user_family_id)
result[user_family.name] = user_family.user_roles.collect(&:title)
end
puts results
But Above query doesn't look optimized one so can anyone help me to write the optimized query.
In our App org_id is present.
Related
I have two double joins (I believe that's what they would be considered) and it just seems awfully slow to do them separately. I know there are debates as to whether or not an individual query is quicker than multiple queries and vice versa but I am willing to try anything.
Here are my existing statements:
line_stops = OpsHeader.joins(
ops_stop_rec: :driver_header
)
.select(
:pbbname,
:pb_net_rev,
:ops_driver1,
:pb_id,
:ops_stop_id,
:dh_first_name,
:dh_last_name,
:ops_delivered_time
)
.where(
:ops_stop_rec => {
ops_arrive_time: params[:startDate] .. params[:endDate]
})
line_items = OpsHeader.joins(
ops_stop_rec: :ops_line_items
).select(
:pbbname,
:opl_amount,
:pb_id,
:ops_type,
:ops_stop_id,
:ops_order_id,
:ops_driver1,
:ops_delivered_time
)
.where(
:ops_stop_rec => {
ops_arrive_time: params[:startDate] .. params[:endDate]
}
)
Just for reference, I am pulling these from an old Firebird Database and the server hardware is not necessarily quick either, so there may be more at play than I am thinking. Also, I have to data manipulation on top of that before I serve it to the client.
Anyway, here are my associations:
class OpsHeader < ApplicationRecord
belongs_to :pb_bill
belongs_to :pb_master
has_many :ops_stop_rec, foreign_key: 'ops_order_id'
self.table_name = 'OPS_HEADER'
self.primary_key = 'pb_id'
end
class OpsStopRec < ApplicationRecord
#belongs_to :ops_order
#belongs_to :ops_im_equip
belongs_to :ops_header, foreign_key: 'pb_id'
belongs_to :driver_header, foreign_key: 'ops_driver1'
has_many :ops_line_items, foreign_key: 'opl_stop_id'
self.table_name = 'OPS_STOP_REC'
self.primary_key = 'ops_stop_id'
end
class OpsLineItem < ApplicationRecord
#belongs_to :opl_order
#belongs_to :opl_stop
belongs_to :ops_stop_rec, foreign_key: 'ops_stop_id'
self.table_name = 'OPS_LINE_ITEMS'
self.primary_key = 'opl_stop_id'
end
class DriverHeader < ApplicationRecord
#belongs_to :dh_paythru
has_many :ops_stop_rec, foreign_key: 'ops_driver1'
self.table_name = 'DRIVER_HEADER'
self.primary_key = 'dh_id'
end
What you're looking for is a union operator. There is a gem which can handle it for you.
Or try using using two left outer joins and add an OR condition.
Please tell me the way how to implement dynamic associative link, which is itself determined by the attribute model.
I have two engines(Tbitcoin, Tstripe) each of them have a table payment. The model User has pay_currency attribute, which is the managing.
class User < ActiveRecord::Base
has_many :payments, ~> { where "pay_currency = 'real'" } , class_name: Tstripe::Payment, foreign_key: :uid
has_many :payments, ~> { where "pay_currency = 'bitcoin'" } ,class_name: Tbitcoin::Payment, foreign_key: :uid
end
What are the ways to dynamically determine the engine using User.last.payments.create ?
I think that you need a regular method instead of has_many association which will find proper payments associated with the user according to pay_currency value. Example:
class User < ActiveRecord::Base
def payments
payment_class = case pay_currency
when "real"
Tstripe::Payment
when "bitcoin"
Tbitcoin::Payment
end
payment_class.for_user(self)
end
end
class Tstripe::Payment < ActiveRecord::Base
belongs_to :user
def self.for_user(user)
where(user_id: user.uid)
end
end
i have this query, which I want to se in rails way. Could please anyone help me here?
select * from users
,buyer_events
,supplier_events
where (users.id = buyer_events.buyer_id
or users.id = supplier_events.supplier_id)
and supplier_events.event_id = 11
and buyer_events.event_id = 11;
PostgreSQL
If more information is needed just write in comments :)
I guess it should be something like this:
class User
has_many :supplier_events
has_many :buyer_events
scope :with_event, ->(event_id) {
joins(:supplier_events, :buyer_events).merge(supplier_events.for_event(event_id)).merge(buyer_events.for_event(event_id))
}
end
class SupplierEvent
belongs_to :supplier, class_name: :User
belongs_to :event, class_name: :Event
scope :for_event, ->(event_id) { where(event_id: event_id) }
end
class BuyerEvent
belongs_to :buyer, class_name: :User
belongs_to :event, class_name: :Event
scope :for_event, ->(event_id) { where(event_id: event_id) }
end
Then issue:
User.with_event(11)
class User < ActiveRecord::Base
...
def self.buyers_and_suppliers user_id
joins(:buyer_events, :supplier_events).where(users: {id: user_id}, supplier_events: {event_id: 11}, buyer_events: {event_id: 11})
end
...
end
I have three models:
Department
class Department < ActiveRecord::Base
has_many :patients, :dependent => :destroy
has_many :waitingrooms, :dependent => :destroy
end
Waitingroom with fields patient_id:integer and department_id:integer
class Waitingroom < ActiveRecord::Base
belongs_to :patient
end
Patient with department_id:integer
class Patient < ActiveRecord::Base
belongs_to :department
has_many :waitingrooms
end
I save a waitingroom after a patient was in the waitingroom! So now i tried to retrieve the patients who where in the the waitingroom of the department:
def index
#waited = #current_department.waitingrooms.patients
end
Somehow it didnt worked it returned this error:
undefined method `patients' for #<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_Waitingroom:0x374c658>
But this worked: What did i wrong? Thanks!
def index
#waited = #current_department.waitingrooms
end
You can't invoke an association on a collection. You need to invoke it on a specific record. If you want to get all the patients for a set of waiting rooms, you need to do this:
def index
rooms = #current_department.waitingrooms
#waited = rooms.map { |r| r.patients }
end
If you want a flat array, you could (as a naive first pass) use rooms.map { |r| r.patients }.flatten.uniq. A better attempt would just build a list of patient ids and fetch patients once:
#waited = Patient.where(id: rooms.pluck(:patient_id).uniq)
I'm having a hard time wrapping my head around how to build this query. I'm not sure if I should try to create a bunch of scopes and try to chain them. Or do I put it into a class method? Or would I do a combo of both? If anyone could give me a short example it would keep me from jumping out the window, I've been working on this for over a week now.
class CensusDetail < ActiveRecord::Base
belongs_to :apartment
belongs_to :resident
end
class Apartment < ActiveRecord::Base
belongs_to :apartment_type
has_many :census_details
has_many :residents, :through => :census_details
end
class ApartmentType < ActiveRecord::Base
has_many :apartments
end
class Resident < ActiveRecord::Base
has_many :census_details
has_many :apartments, :through => :census_details
end
apartment.rent_ready = boolean value if apartment is ready
apartment_type.occupany = the number of allowed occupants in an apartment
census_detail.status = either "past", "present", or "new"
census_detail.moveout_date = date time resident is scheduled to move out
I need to build a query that does the following:
- if the apartment is rent ready then do the following:
- pull a list from census_details of all residents set as "current" for each apartment
-if the # of residents is less than the value of apartment_type.occupancy for this
apartment, then list it as available
-if the # of residents is = to the value of apartment_type.occupancy then
-does any resident have a scheduled move out date
-if not, do not list the apartment
-if yes, then list apartment
Thanks in advance for any help or suggestions.
I haven't cleaned it up yet, but this is working for me, so I wanted to share.
apartment_type.rb
class ApartmentType < ActiveRecord::Base
has_many :apartments, :dependent => :nullify
end
census_detail.rb
class CensusDetail < ActiveRecord::Base
belongs_to :resident_contacts
belongs_to :apartments
scope :get_current_residents, ->(id) { where("status = ? and apartment_id = ?", "current", id) }
end
apartment.rb where most of the work is happening
class Apartment < ActiveRecord::Base
belongs_to :apartment_type
has_many :census_details
has_many :residents, :through => :census_details
scope :rent_ready, -> { where(:enabled => true) }
def self.available
available_apartments = []
rent_ready_apartments = self.rent_ready.all
rent_ready_apartments.each do |apt|
tmp = ApartmentType.where('id = ?', apt.apartment_type_id).pluck(:occupancy)
occupancy = tmp[0]
current_residents = CensusDetail.get_current_residents(apt.id)
resident_count = current_residents.count
if resident_count < occupancy
available_apartments << apt
end
if resident_count = occupancy
scheduled = false
current_residents.each do |res|
if res.moveout_date
scheduled = true
end
end
if scheduled == true
available_apartments << apt
end
end
end
available_apartments
end
end
The code is a bit ugly but its so far passing my tests. I would have edited my original question instead of answering in case someone has a better way of doing this but each time I do my question gets voted down. If anyone knows a better way please let me know because I'm at a point in the app where there are about 50 tables and now it's all getting tied together with complex queries.