Complex Queries in Rails

Rails and ActiveRecord do just fine so that I would consider extremely simple queries regarding one model. I now have a situation where I need to do something a little more complicated, but still trivial - and I donโ€™t know how to do it.

I have User that has_many :images . Each Image has_many :thumbnails .

On my /images index page, I really want to display a small thumbnail for each image that belongs to a registered user. An easy query, but since this is due to the conditions for multiple tables, I'm not sure how to approach it in real Rails mode. I would prefer to avoid writing SQL and eliminating the headaches that arise.

I see that the rails offer an option :joins , but this seems like a rather inelegant belated thought. Is this the best way to satisfy this requirement or is there a better way that I just could not find?

Thanks.

UPDATE: I was told about these areas and must admit that they have some unulocal feelings for them right now. They allow quite difficult conditions to be applied very elegantly with a lot of syntactic sugar. For example, I can create a named area in my image model for images belonging to this user and make it dynamic:

 class Image < ActiveRecord::Base named_scope :owned_by, lambda { |user_id| { :conditions => { :user_id => user_id } } } end 

I can also apply a named area to my miniature model to indicate a small thumbnail:

 class Thumbnail < ActiveRecord::Base named_scope :small, :conditions => { :name => 'Small' } end 

Now I can combine them together to make pretty powerful stuff that reads great. In my controller, I can return all images for a given user:

 @images = Image.owned_by( current_user ) 

However, in my opinion, I want to display a small thumbnail, so we are very strongly connected:

 <% for image in @images %> <tr> <td><%= h( image.name ) %></td> <td><%= link_to( image_tag( image.thumbnails.small.first.binary.uri, :alt => h( image.name ), :title => h( image.description ) ), :action => :show, :id => image.id ) %></td> </tr> <% end %> 

Check out image_tag . For each image, he identifies the first small thumbnail, and then links it to get the physical location of the file. This is not exactly what I was looking for, since an extra byte is required for each image, but it is probably more accurate for my needs in this particular case.

+4
source share
3 answers

RailsGuides are always convenient for this, I spent a lot of time there.

Check has_many: through an association that allows image models to join these tables and allow additional fields related to the image.

 Thumbnail has_many :images has_many :users, :through => :images Image belongs_to :user belongs_to :thumbnail User has_many :images has_many :thumbnails, :through => :images 

Then, when accessing the Thumbnails associated with the user that you could do;

 @user.thumbnails 

Or maybe Thumbnail should have one image and one user?

 Thumbnail belongs_to :image Image belongs_to :user has_one :thumbnail User has_many :images has_many :thumbnails, :through => :images 

In this example, I drew this from.

+3
source

To write complex queries beautifully, you could use something like protein. Squirrel is a plugin that allows you to write complex queries in a more natural way:

 User.find(:all) do first_name == "Jon" # first_name = 'Jon' email =~ "%@thoughtbot.com" # email LIKE '%@thoughtbot.com' created_at >= 4.years.ago # created_at >= '2004-06-27 10:34:22' awesomeness <=> (1..10) # awesomeness BETWEEN 1 AND 10 banned_since == nil # banned_since IS NULL end 

You can even use associations (which you need):

 Post.find(:all) do user.first_name.contains? "Jon" end 

More information on Squirrel - Natural Searches for Rails . Also, be sure to check out your wiki page on Github.

+2
source

for a specific user, you can find all the thumbnails by doing something like this

 @user = User.find(:id, :include => :thumbnails) 

: Thumbnails must be defined in the user model, as his answer shows an association of type revgum.

0
source

All Articles