Rails: What's Wrong with This Multiple Join with Conditions on The Associations

rails : what's wrong with this multiple join with conditions on the associations?

You need to complete your association with the Card model:

class Card < ActiveRecord::Base
has_many :deck_cards
end

EDIT 2: Try this:

 DeckCard.find :all, :joins => [:card, :deck], :conditions => ["decks.game_id = ? and cards.present = ?", @game.id, true]

Eager Loading multiple rails associations with multiple conditions

@clients = Client.includes([:contacts, :addresses]).where(some_parameters)

Then in your view you can reference the relationships as normal without touching the database again since the tables have been loaded into memory via the includes method.

For conditionals this will help:

Client.includes([:contacts, :addresses]).where('contact.name = ?', 'example').references(:contacts)

ActiveRecords Join with conditions: how to join on the same table with different sets of conditions using squeel sifters?

This is the case where you need to take the intersection of sets of users. In other words, you need to apply the "AND" to the sets of users, not to the where conditions. When you chain where conditions, you are "anding" the conditions, which is why you see the results you're seeing.

You can do this either in Ruby or in SQL, using the basic technique described in Intersection of two relations. For the sake of simplicity, I'll illustrate both here using two sets and leave the extension to more than two sets and to squeel to you.

First, let's define two sets:

set1 = User.joins(:user_skills).where('user_skills.skill_id = 10')
set2 = User.joins(:user_skills).where('user_skills.skill_id = 11 and user_skills.value >= 2')

Note: Your example text said "value higher than 2" but your code expressed "value greater than or equal to 2". I obviously used the latter interpretation above.

If you want to take the intersection in Ruby, you take the intersection of the resulting arrays, using the & operator, as follows:

set1 & set2

In this case, you are doing two separate SQL queries and taking the intersection of the results.

If you want to take the intersection using SQL, you need to compose the SQL, which can be done using the technique described in this answer from @MikDiet to the aforementioned question:

User.connection.unprepared_statement do
User.find_by_sql "#{set1.to_sql} INTERSECT #{set2.to_sql}"
end

In this case, you are performing a single query, although that query is obviously doing "more work". You should read the original answer to understand the reason for use of unprepared_statement.

I'll leave the extension to squeel and greater than two sets to you except to note that you can use the SQL INTERSECT operator with more than two operands as follows:

query1 INTERSECT query2 INTERSECT query3 ...

JOIN ON ... AND conditions when eager loading association in ActiveRecord

If I am right, you only want to eager load the subset of the associations. Well, in order to do so, you need to outsmart the rails . You can basically create another association such as "highest_grade" to fetch the grades with level A+ using a where clause inside the ruby lambda. This can be achieved by using the following snippet of code

class Parent
has_many :children
has_many :grades, through: :children
has_many :highest_grade, ->{where(level: 'A+')}, class_name: "Grade", through: :children
end

Now you need to eager load the highest_grade association.

 Parent.eager_load(:highest_grades)

This will essentially load all the parents along with only those grades whose level is A+.

It generates the following query.

 SQL (0.3ms)  SELECT `parents`.`id` AS t0_r0, `parents`.`created_at` AS    t0_r1, `parents`.`updated_at` AS t0_r2, `grades`.`id` AS t1_r0,    `grades`.`child_id` AS t1_r1, `grades`.`created_at` AS t1_r2, `grades`.`updated_at` AS t1_r3, `grades`.`level` AS t1_r4 FROM `parents` LEFT OUTER JOIN `children` ON `children`.`parent_id` = `parents`.`id` LEFT OUTER JOIN `grades` ON `grades`.`child_id` = `children`.`id` AND `grades`.`level` = '

If you want to understand how this works. Please use this link as a reference



Related Topics



Leave a reply



Submit