-1

In my application I have two models:

class Address < ActiveRecord::Base
  belongs_to :location
end

class Location < ActiveRecord::Base
  #it has field city:string
  has_one :address
end

Now I want to find all Locations which address city field have value: "test". How can I do that? Thank's in advance.

Mateusz Urbański
  • 7,352
  • 15
  • 68
  • 133

3 Answers3

5
Location.includes(:address).where(city: "test")
Sachin R
  • 11,606
  • 10
  • 35
  • 40
3

Since nobody else bothered to explain why you would use includes vs joins:

Assume data:

addr1 = Address.create(street: "1 Unique Street", city: "test")
addr2 = Address.create(street: "2 Unique Street", city: "test")
Location.create(name: "Location 1", address: addr1)

Joins:

Location.joins(:address).where(addresses: { city: "test" })

# performs INNER JOIN
#> [#<Location id: 1, name: "Location 1">,
     #<Location id: 1, name: "Location 1">]

Includes:

Location.includes(:address).where(addresses: { city: "test" })

# performs LEFT OUTER JOIN
#> [#<Location id: 1, name: "Location 1">]

If you use joins, use distinct:

Location.joins(:address).where(addresses: { city: "test" }).distinct(:location)

#> [#<Location id: 1, name: "Location 1">]

The reason is because of the INNER JOIN that joins performs. See more information here: What is the difference between "INNER JOIN" and "OUTER JOIN"?

Community
  • 1
  • 1
Damien Roche
  • 13,189
  • 18
  • 68
  • 96
1
Location.joins(:address).where(addresses: {city: "test"})
gwcoffey
  • 5,551
  • 1
  • 18
  • 20
  • 1
    Better to use `includes` rather than `joins`. – Pavan Jun 02 '14 at 07:23
  • 1
    @Pavan Using `includes` would be more complicated because you'd need a `references` too, you'd left join unnecessarily, and you'd eager-load addresses, which isn't explicitly needed here. Why not just use `joins`? – gwcoffey Jun 02 '14 at 07:26
  • 1
    @gwcoffey Yup!But `joins` creates duplicates – Pavan Jun 02 '14 at 07:27