Rails order by association field
SqlRuby on-RailsPostgresqlSql Problem Overview
I have the following models
class User
attr_accesible :first_name, :phone_number
has_one :user_extension
end
class UserExtension
attr_accessible :company, :user_id
belongs_to :user
end
I have table which contains all users. And I need to sort this table by first_name, phone_number, company. With first_name, phone_number I don't have any problems, order works fine, in example
@users = User.order("first_name desc")
, but I also need sort by company and don't know how to do it.
And I can get company name by this way
@user.user_extension.company
So i have troubles with sql, which will gave me all users ordered by company. DB: PostgreSQL. Thanks.
Edit:
I should provide more information about this models.
create_table "user_extensions", :force => true do |t|
t.integer "user_id"
t.string "company"
end
create_table "users", :force => true do |t|
t.string "first_name"
t.string "phone_number"
end
Also, I tried use join
User.joins(:user_extension).order("user_extension.company desc")
and what i get
User Load (1.6ms) SELECT "users".* FROM "users" INNER JOIN "user_extensions" ON "user_extensions"."user_id" = "users"."id" ORDER BY user_extension.company desc
PG::Error: ERROR: relation "user_extensions" does not exist
on
User.includes(:user_extension).order("user_extension.company desc")
i also get
PG::Error: ERROR: relation "user_extensions" does not exist
Resolved Have problems with my bd, all joins works fine.
Sql Solutions
Solution 1 - Sql
Try this:
@users = User.includes(:user_extension).order("user_extensions.company desc")
I think you need at order
: user_extensions
, not user_extension
Solution 2 - Sql
Merge can make the query smaller/saner-looking, and it benchmarked faster for me in Rails 4.x:
@users = User.joins(:user_extension).merge(UserExtension.order(company: :desc))
Solution 3 - Sql
@users = User.order("user_extension.company desc")
should work fine.
Solution 4 - Sql
Old topic, and perhaps off topic, but I needed this. FWIW:
Order by association field
User.includes(:user_extension).order('user_extensions.company ASC')
Lets make it more interesting, create more associations.
Order by the associations two levels deep.
User.includes(user_extension: :company).order('companies.name ASC')
Order by the associations three levels deep.
User.includes(user_extension: { company: :guilds }).order('guilds.secret_knock ASC')
Solution 5 - Sql
Maybe too late but I ran into a similar issue and this is how I implement it:
scope :sort_by_company, ->{
joins(:user_extension).order(UserExtension.arel_table[:company].lower.desc)
}
The code above should be placed within the user model
.
Hope it can help!