I have a model called "activos", I need to show only the records that are not associated with another model called "relactivo".
I've been trying this in the model: scope :ts, -> { includes(:relactivo).where(relactivo: { activo: nil}) }
this is my model "activos"
class Activo < ActiveRecord::Base
self.primary_key = "IdActivos"
scope :ts, -> { includes(:relactivo).where(relactivo: { activo: nil}) }
has_one :relactivo, class_name: "Relactivo", foreign_key: "Activo"
end
and my model "relactivo"
class Relactivo < ActiveRecord::Base
self.primary_key = "IdRow"
belongs_to :activo, class_name:"Activo", foreign_key: "Activo"
end
Try doing this for your scope:
class Activo < ActiveRecord::Base
self.primary_key = "IdActivos"
scope :ts, -> { joins('LEFT OUTER JOIN relactivos ON relactivos.IdActivos = activos.IdActivos WHERE relactivos.IdActivos IS null'))) }
has_one :relactivo, class_name: "Relactivo", foreign_key: "IdActivos"
end
See if this works, The custom primary/foreign key makes it a little strange but try this.
Related
In Rails 4 I am using:
class Ticket < ActiveRecord::Base
has_many :request_attendances, dependent: :destroy
has_many :attending_request_attendances, -> {
where("data->>'rsvp_completed' = 'true'")
.where("data->>'is_coming' = 'true'")
}, class_name: 'RequestAttendance'
end
In my Tickets model
And
class RequestAttendance < ActiveRecord::Base
belongs_to :tickets, inverse_of: :request_attendances
scope :is_coming, -> { where("data->>'is_coming' = 'true'")}
scope :rsvp_completed, -> { where("data->>'rsvp_completed' = 'true'")}
end
In my RequestAttendance model
I would like to do something like this
has_many :attending_request_attendances, -> {
:is_coming
:rsvp_completed
}, class_name: 'RequestAttendance'
To reuse the scope I have created in my RequestAttendance model.
Is something like this possible, at the moment it does not work, giving me the following error:
undefined method `except' for :rsvp_completed:Symbol
If I add a where to the has_many block like this:
has_many :attending_request_attendances, -> {
:is_coming
:rsvp_completed
where("data->>'rsvp_completed' = 'true'")
}, class_name: 'RequestAttendance'
It does not error, however it also does not use the scope clauses either.
You can chain scopes together inside an association like this:
has_many :attending_request_attendances, -> {
is_coming.rsvp_completed
}, class_name: 'RequestAttendance'
You have added the below code in RequestAttendance model
scope :is_coming, -> { where("data->>'is_coming' = 'true'")}
scope :rsvp_completed, -> { where("data->>'rsvp_completed' = 'true'")}
if you use the below code in Tickets Model
class Tickets < ActiveRecord::Base
has_many :RequestAttendance
end
scopes are available to has_many associations so it will fetch all the records with is_coming' = 'true' and "data->>'rsvp_completed' = 'true'"
You can fetch it using object tickets.requestAttendance.is_coming.rsvp_completed
Is it your expectation or If I misunderstood pls explain
I have:
price_plan.rb
class PricePlan < ActiveRecord::Base
has_many :users
scope :premium, lambda { where('price > ?', 0) }
scope :free, lambda { where('price == ?', 0) }
end
user.rb
class User < ActiveRecord::Base
belongs_to :price_plan
has_one :account
scope :free, lambda { joins(PricePlan.free) } #<--- no!
end
How to define scope for users, that use service free of charge?
This below should work, but I don't like it.
scope :free,-> where(priceplan_id: PricePlan.free.pluck(:id))
It will be
Solution 1: Use condition on relation
class User < ActiveRecord::Base
# Your current code
belongs_to :free_price_plan, -> { free }, class_name: 'PricePlan'
belongs_to :premium_price_plan, -> { premium }, class_name: 'PricePlan'
end
Solution 2: Define a scope
class User < ActiveRecord::Base
# Your current code
scope :free, -> {
joins(:price_plan).merge(PricePlan.free)
}
scope :premium, -> {
joins(:price_plan).merge(PricePlan.premium)
}
end
Quick question here. Given the following example many-to-many relationship, how would I query the Physician table for appointments they have today?
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, through: :appointments
end
On the Physician model I have the following:
scope :for, -> (name) { find_by_name(name: name) }
# I need a hand here, the join I assumed would work didn't seem to filter properly.
# scope :appointments_today, -> { joins(:appointment).where("appointments.appointment_date = ?", Date.today) }
scope :appointments_today, -> { ??? }
I'd like to chain queries on the controller as such:
data = Physician.for("test").appointments_today
Do you want a list of Physician records that have an appointment scheduled for today, or do you want a list of Appointment records that are for a specific physician and are scheduled for today?
Physicians that have an appointment today:
Physician.
joins(:appointments).
where(
name: "test",
appointments: {
appointment_date: (Date.today.beginning_of_day..Date.today.end_of_day)
}
)
Appointments for a physician that are today:
Appointment.
joins(:physician).
where(
appointment_date: (Date.today.beginning_of_day..Date.today.end_of_day),
physicians: { name: "test" }
)
As scopes, you can do physicians that have an appointment today:
class Physician < ActiveRecord::Base
scope :named, -> (name) { where(name: name) }
scope :with_appointments_on, -> (date) { joins(:appointments).where(appointments: { appointment_date: (date.beginning_of_day..date.end_of_day) })}
end
Physician.named("test").with_appointments_on(Date.today)
Or appointments for a physician that are today:
class Appointment < ActiveRecord::Base
scope :on_date, -> (date) { where(appointment_date: (date.beginning_of_day..date.end_of_day)) }
end
Physician.find_by_name("test").appointments.on_date(Date.today)
Try to do this
scope :for, -> (name) { where(name: name) }
Next, you have to add plural into appointments
scope :appointments_today, -> { joins(:appointments).where("appointments.appointment_date = ?", Date.today) }
I hope this help you.
If you are trying to fetch a list of appointments, the logic should go in the Appointment model:
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
scope :for_today, -> { where('appointments.appointment_date >= ? AND appointments.appointment_date < ?', Time.zone.now.beginning_of_day, Time.zone.now.end_of_day) }
scope :for_physician, -> (name) { joins(:physician).where(physicians: {name: name}) }
end
And the you can find the appointments by:
data = Appointment.for_today.for_physician("test")
I have a class for a child
class Child < BaseModel
attr_protected
has_many :child_parent_relationships, :dependent => :destroy
has_many :child_daycare_relationships, :dependent => :destroy
has_many :child_class_relationships, :dependent => :destroy
has_many :parent_users, :through => :child_parent_relationships
has_many :attendance_records
has_many :moods
has_many :behaviors
validates :first_name, :presence => true
end
When I get the child Child.find(id) it returns all of the has_many relations. How do I return the child but then limit the relations of say the mood table by a field value like date?
You can do this a couple ways.
If you have a child variable
#child = Child.find(id)
You can add scopes to Mood and Behaviors, or where clauses. So you ask for something like
#child.moods.where(field: "value")
or
class Behavior < ActiveRecord::Base
scope :filtered, -> { where(field: "value") }
end
# Use scopes like so
#child.behaviors.filterd
To use a date in a scope, it would be something like this
scope :on_date, -> (date) { where field: date }
scope :before_date, -> (date) { where("behaviors.field < ?", date) }
you can also set up has many relationships to prefilter
class Child < ActiveRecord::Base
has_many :specific_moods, -> { where(field: "value" }, class_name: "Mood"
has_many :certain_behaviors, -> { where(field: "value" }, class_name: "Behavior"
end
Then you can use this in your views:
#child.specific_moods
#child.certain_behaviors
Just append the conditions you need.
Child.find(id).moods.where(field: "value")
I have the following resources:
- restaurant
- category
- item
- check item
Relationship:
class Restaurant < ActiveRecord::Base
has_many :items
has_many :categories
has_many :check_items
class Category < ActiveRecord::Base
belongs_to :restaurant
has_many :items
class Item < ActiveRecord::Base
belongs_to :restaurant
belongs_to :category
class CheckItem < ActiveRecord::Base
belongs_to :item
I need to filter all the check_items of a restaurant where category.uuid = '123123'
so I have my #restaurant.check_items. How do I join these together to basically implement this sql query:
SELECT * from checkitem
INNER JOIN item ON(checkitem.item_id = item.id)
INNER JOIN category ON(category.id = item.category_id)
WHERE category.restaurant_id = 1 AND category.uuid = '123123'
LIMIT 20;
I've tried with scope:
#already have my restaurant resource here with id 1
#restaurant.check_items.by_item_category params[:category_uuid]
And in my models I would have:
class CheckItem < ActiveRecord::Base
...
scope :by_item_category, -> value { joins(:item).by_category value }
class Item < ActiveRecord::Base
...
scope :by_category, -> value { joins(:category).where('%s.uuid = ?' % Category.table_name, value)}
Buut this doesn't seem to work
This appears to be the only way I found this to be working if anyone is interested.
CheckItem.joins(:item => {:category => :restaurant}).where('category.uuid=? and restaurant.id=?', 123123, 1)