Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to ask for only certain columns from an ActiveRecord association?

consider

def Foo
  has_one :user
end

let's say i only want a Foo's User's name, and not any of the other columns. so i want

SELECT name FROM "users" WHERE "prices"."id" = 123

but doing foo.user.name will give me

SELECT * FROM "users" WHERE "prices"."id" = 123

is there any slick way to use the association to get only one column? if not, then i have to do:

User.where(id: foo.user_id).pluck(:name).first
like image 416
John Bachir Avatar asked Apr 19 '13 19:04

John Bachir


People also ask

How many types of associations are there in Rails?

Rails supports six types of associations: belongs_to.

How do associations work Rails?

Association in Rails defines the relationship between models. It is also the connection between two Active Record models. To figure out the relationship between models, we have to determine the types of relationship. Whether it; belongs_to, has_many, has_one, has_one:through, has_and_belongs_to_many.

What is a polymorphic association in Rails?

Polymorphic relationship in Rails refers to a type of Active Record association. This concept is used to attach a model to another model that can be of a different type by only having to define one association.

What are associations in Rails?

What is an association in Rails? In Rails, an association can be defined as a relationship between two Active Record models. For example, in the Granite application, a task created by a user. And each user can create multiple tasks thus building a relationship between the User and Task models.


2 Answers

In general you can specify what columns you want to select using the .select method, like:

User.select(:name).where(...)

This will return just the values from the name column. You can chain this onto an association, but not onto an instance. So, as meagar very agressively pointed out by downvoting the other answers (including Mori's deleted answer), in a has_one relationship you can't chain this on the association (because it's not an association in that case). However, you could build a custom scope, like this:

class Foo < ActiveRecord::Base
  has_one :bar
  scope :bar_name, lambda {Bar.select(:name).where(:foo_id=> id)}
end

The above is untested so you may have to tweak it, but generally speaking that approach would allow you to do something like:

foo.bar_name

...without loading all the columns from Bar.

like image 156
Andrew Avatar answered Oct 05 '22 23:10

Andrew


No, in the case of your has_one, but yes in the case of has_many.

The object returned for a has_one association isn't a scope onto which you can chain additional methods like select, like with a has_many. It's an actual instance of the model, and instantiating it will necessarily involve a select *.

If you want to select just the name, you'll have to access the User model directly and use select.

Conversely, if your Foo has many users, you could use foo.users.select("name") or any of the other chainable methods, as foo.users would be an actual ActiveRecord association, not an instance of a model.

like image 40
meagar Avatar answered Oct 06 '22 00:10

meagar