Rails Nested Query - ruby-on-rails

I have follow query
notes = Note.where('notes.id IN
(
SELECT "notes"."id" FROM "notes"
WHERE "notes"."circle_id" = ?
)
OR notes.id IN
(
SELECT "notes"."id" FROM "notes"
INNER JOIN "circles_dreams"
ON "circles_dreams"."dream_id" = "notes"."dream_id"
WHERE "circles_dreams"."circle_id" = ?
)', #circle.id, #circle.id)
How to simplify this query?
Thanks.

First of all you can collect all needed notes id.
I supposed to think what you already have relations between Note and CirclesDream
note_ids = Note.where(circle_id: #circle.id).pluck(:id) # your first SELECT
dream_ids = CirclesDream.where(id: #circle.id).pluck(:note_id) # your second SELECT
notes_ids = note_ids | dreams_ids # combine them
notes = Note.where(id: notes_ids) # Now your
upd: I've just fixed typo. Changed id to note_id in second request

Try this
note_ids = Note.where('circle_id = ?', #circle.id).pluck(:id)
dream_note_ids = Note.joins(:circle_dreams).where('circle_dreams.circle_id = ?', #circle.id).plunk(:note_id)
notes_ids = note_ids | dream_note_ids
If your circle_dreams table can contain records having note_id = null, then you have to apply join. So i think this will work in your case....

Related

Rails find_by_SQL with Rails

I'm using a find_by_sql method to search users in my userstable.
is there a possibility to use rails code in the select statement?
User.find_by_sql ["SELECT DISTINCT
users.*
FROM
users
JOIN
clients_courses cc
ON
cc.client_id = users.client_id
LEFT JOIN
memberships m
ON
m.user_id = users.id AND m.course_id = cc.course_id
WHERE
cc.course_id = ?
AND
m.user_id IS NULL
AND
users.active = ?
AND
users.firstname LIKE ? or users.lastname LIKE ?
AND NOT IN ( RAILS CODE )", self.id, true, "#{search}%", "#{search}%"]
end
I Marked the position with RAILS CODE
I want to do someting linke this:
Membership.where("course_id = ?", self.id).users
is there a way to do this?
You can do this -
member_user_ids = []
Membership.where("course_id = ?", self.id).map{|membership| membership.users.map{|user| member_user_ids << user.id}}
# you might want to put a uniq! on member_user_ids
User.find_by_sql ["SELECT DISTINCT
users.*
FROM
users
JOIN
clients_courses cc
ON
cc.client_id = users.client_id
LEFT JOIN
memberships m
ON
m.user_id = users.id AND m.course_id = cc.course_id
WHERE
cc.course_id = ?
AND
m.user_id IS NULL
AND
users.active = ?
AND
users.firstname LIKE ? or users.lastname LIKE ?
AND users.id NOT IN ( #{member_user_ids.join(',')} )", self.id, true, "#{search}%", "#{search}%"]
You can also have a look at link which explains how to put array of strings in where clause.

NOT EXISTS SQL query in rails 3.2

I have an sql query like this:-
SELECT * FROM `permissions` join entities where NOT EXISTS (select
entity_id,permission_id from role_permissions where role_id=5 and
entities.id = role_permissions.entity_id and permissions.id =
role_permissions.permission_id)
I would like to get the corresponding rails query.
I have tried this.
Permission.joins("join entities").joins("LEFT OUTER JOIN role_permissions on
permission_id != permissions.id and entities.id != entity_id and
role_permissions.role_id= role_id").select("role_permissions.entity_id,role_permissions.role_id,
role_permissions.permission_id").group('role_permissions.entity_id,
role_permissions.permission_id')
But it doesn't works.
thanks
hari
I have been particularly in love with EXISTS queries lately, precisely because it does not require you to fully join another table. As far as I know, you do have to explicitly write the SQL clause, but you can still make it work with Activerecord. You can even put this in a scope within a lambda block.
Permission.joins(:entities).where(<<-SQL
NOT EXISTS(
select
* from role_permissions where role_id=#{your_role_id} and
entities.id = role_permissions.entity_id
and permissions.id = role_permissions.permission_id
)
SQL
)
Try like this for a default SQL query:
sql = "SELECT some_field FROM `permissions` join entities where NOT EXISTS (select entity_id,permission_id from role_permissions where role_id=5 and entities.id = role_permissions.entity_id and permissions.id = role_permissions.permission_id)"
results = ActiveRecord::Base.connection.execute(sql)
results.each do |result|
#register_users << { some_field: result[0] }
end
Try this
UPDATED BASED ON FIRST COMMENT
Permission.joins(:entities).joins("LEFT OUTER JOIN role_permissions on
permission_id != permissions.id and entities.id != entity_id and
role_permissions.role_id= role_id")
.select("role_permissions.entity_id,role_permissions.role_id,
role_permissions.permission_id")
.group('role_permissions.entity_id, role_permissions.permission_id')

how to convert sql query in ruby and rails?

SELECT A.FirstName, A.LastName, B.PatientId, B.RoomNumber, B.AdmissionDate, B.DischargeDate, B.MeasureCategory
FROM DimPatient A, DimPatientStay B
WHERE A.Id = B.PatientId AND A.FirstName = 'Anuj' AND B.MeasureCategory = 'ED'
hi some updation for this
i solved this prob by
MODELNAME.find_by_sql("your sql query")
You can try this to find the result from sql query in Rails
query_params = Hash.new
sql_query = "SELECT A.FirstName, A.LastName, B.PatientId, B.RoomNumber, B.AdmissionDate, B.DischargeDate, B.MeasureCategory
FROM DimPatient A, DimPatientStay B
WHERE A.Id = B.PatientId AND A.FirstName = :first_name AND B.MeasureCategory = :measure_category"
query_params[:first_name] = first_name
query_params[:measure_category] = measure_category
#query_results = ActiveRecord::Base.connection.select_all(
ActiveRecord::Base.send("sanitize_sql_array",[sql_query, query_params] )
)
I guess you could try:
ActiveRecord::Base.connection().execute(#your_sql_here)
Suppose A is one class and B is another, you should use includes as following:
A.includes(:b).where(...) # add you condition in where
I suggest to check good video tutorials of ActiveRecord here

psql excluding records base on another table

i am using postgres and wishing to exclude users that are currently in one table from another. at present i am trying do this via the ActiveRecord system within Rails.
So i need it to get the ids from my Availability table, then return that id into my User table to remove them if they are in the Availability table.
#availabilities = Availability.where(:event_id => params[:id]).all
#players = User.where('team_id = ? and id <> ?', current_user[:team_id], #availabilities).all
this is returning the following error
PG::Error: ERROR: argument of WHERE must be type boolean, not type record
LINE 1: SELECT "users".* FROM "users" WHERE (team_id = 1 and id <> ...
^
: SELECT "users".* FROM "users" WHERE (team_id = 1 and id <> 101,102,103)
changed code as mentioned below, though the way i am doing it is still probably not ideal
#availabilities = Availability.where(:event_id => params[:id]).all
#exclude = Availability.where(:event_id => params[:id]).select(:user_id).pluck(:user_id)
if #exclude.count > 0
#players = User.where('team_id = ? and id NOT IN (?)', current_user[:team_id], #exclude).all
else
#players = User.where('team_id =?', current_user[:team_id])
You could do something like this:
#availabilities = Availability.where(event_id: params[:id]).pluck(:id)
#players = User.where(team_id: current_user[:team_id])
#players = #players.where('id NOT IN (?)', #availabilities) unless #availabilities.empty?
Using pluck() will return an array of IDs, then you can exclude them by using NOT IN (?)
Try:
id not in
The way pg engine sees it is ((team_id=1 and id <> 101), 102, 103). Thus the error you see.
Use it as:
User.where('team_id = ? and id not in (?)', current_user[:team_id], #availabilities).all

wordpress query filtering by custom-field, tag and category

i have made this query to select posts from a WordPress blog filtering by Category, Tag and Custom Fields.
SELECT wp_posts.*
FROM wp_posts
WHERE wp_posts.post_type = 'post' AND wp_posts.post_status = 'publish'
AND ( SELECT COUNT(*)
FROM wp_term_relationships
LEFT JOIN wp_term_taxonomy ON ( wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id )
LEFT JOIN wp_terms ON ( wp_term_taxonomy.term_id = wp_terms.term_id )
WHERE wp_posts.ID = wp_term_relationships.object_id
AND ( wp_terms.name = 'collaborazioni' && wp_term_taxonomy.taxonomy = 'category' )
||
( wp_terms.name = 'jammin' && wp_term_taxonomy.taxonomy = 'post_tag' )
) >= 1
AND ( SELECT COUNT(*) FROM wp_postmeta
WHERE wp_postmeta.post_id = wp_posts.ID
AND wp_postmeta.meta_key = 'Product-code'
AND wp_postmeta.meta_value = 'xxxxxx'
) >= 1
but i think that is a little heavy .. did you have some better solution ?
thanks, Pietro.
What exactly would you like to make shorter? It already looks shorten pretty well.
PS. You might want to use {$wpdb->prefix} instead of wp_ in queries.

Resources