I'm not strong in sql and relatively new to rails. The
Case
attr_accessible client_id
belongs_to Client
Client
attr_accessibe name
has_many Cases
I can query directly by client_id and get a record back as expected
Case.where(client_id: 1)
But I would like to query by client.name
Case.where(client.name => "Foo")
This give me an error that tells me that client is not a method of case.
Undefined method or local variable
Ultimately, what I'm trying to do is very simple: get the first Case that belongs to client "Foo". The query I would expect to use is this.
Case.where(client.name => "Foo").first
What should it be?
They essentially do the same thing, the only difference is what side of the relationship you are on. If a User has a Profile , then in the User class you'd have has_one :profile and in the Profile class you'd have belongs_to :user .
The Relation Class. Having queries return an ActiveRecord::Relation object allows us to chain queries together and this Relation class is at the heart of the new query syntax. Let's take a look at this class by searching through the ActiveRecord source code for a file called relation.
Active Record uses naming conventions for the columns in database tables, depending on the purpose of these columns. Foreign keys - These fields should be named following the pattern singularized_table_name_id (e.g., item_id , order_id ).
in Ruby, :: accesses static class or module constants. ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending.
Case.joins(:client).where(clients: { name: 'foo' })
This query will joins the clients on the case table (eliminates the Cases without any client associated) and add the where clause "where clients.name = 'foo'"
In human language, this query does:
Get the Cases having at least one Client having the name strictly equal (case-sensitive) to 'foo'
Pay attention to the plural/singular:
in the joins/includes, use the same name as the relation is declared in the model
in the where clause, always use the pluralized version of the relation (actually the table's name)
Additionnal informations:
You can use an array of values in the where clause:
Case.joins(:client).where(clients: { id: [1,2,5] })
Difference between .joins
and .includes
: Rails :include vs. :joins
Depending on what you're doing it may be easier to go about it this way:
Client.where(:name => "foo").first.cases
This will return all the cases for the client.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With