raphael_turtle
raphael_turtle

Reputation: 7314

find a random entry from an association in rails

Controller:

class GalleriesController < ApplicationController
  def index
    @galleries = Gallery.all
  end
end

View:

<% for gallery in @galleries %>
  <%= image_tag(gallery.image.url(:medium)) %>
<% end %>

I have 2 models, Photo which belongs to Gallery,which has many Photos. I want to display an image (preferably random rather than :first) from each gallery on the gallery index page. I know the code I have is wrong as I haven't described which image to select from the gallery, but I'm not sure how to do this... I thought that using @photos = @galleries.photos.find(:first) would work but I get an undefined method 'photos' in the controller.

Upvotes: 3

Views: 918

Answers (3)

jigfox
jigfox

Reputation: 18177

This works in Rails 2 + MySQL

class Photos < ActiveRecord::Base
  # for MySQL:
  named_scope :random, lambda { |n| {:order => "RAND()", :limit => n || 1 }}
  # for SQLite and PostgreSQL
  named_scope :random, lambda { |n| {:order => "RANDOM()", :limit => n || 1 }}
end

Then you can do something like

gallery.photos.random[0]

gallery.photos.random will return 1 Photo randomly, but it will still return an array, that's why you need the [0] to get the first element of this array. you can also do gallery.photos.random.first.

If you want more than one random image you can call gallery.photos.random(10) to get 10 random photos.

Upvotes: 3

Steve Weet
Steve Weet

Reputation: 28402

You are asking the @galleries array for its photos which will not work. You need to ask an instance of Gallery for its photos.

So within your for loop then the following should work for you

<% for gallery in @galleries %>
<%= image_tag(gallery.photos.first.image.url(:medium)) %>

If you want to get one photo in Random order then you could adpot Salils suggestion or perhaps add a method to the Gallery model as follows :-

def random_image()
  photos.all[rand(photos.all.size)]
end

And then within your foreach loop just do <%= image_tag(gallery.random_image) %>

Upvotes: 0

Salil
Salil

Reputation: 47512

@galleries is an array so you can't write @galleries.photos.find(:first) but you have to write @galleries[0].photos.find(:first)

for random order try following

<% for gallery in @galleries %>

<%= image_tag(gallery.photos.order('rand()')) %>

Upvotes: 0

Related Questions