sábado, 28 de marzo de 2009

Combinación de named_scopes en rails

Cuando hay que realizar un filtrado de resultados en una web con muchas posibles combinaciones podemos acabar con muchas líneas de código para obtener una funcionalidad no demasiado compleja.

En rails, la mayoría de los filtrados se hacen con named_scopes, queda parcialmente resuelto el problema, aún así quedan resolver como aplicar cada combinación de named_scopes según el filtrado que necesite el usuario.

Suponiendo que tenemos un modelo Post como el siguiente:

class Post < ActiveRecord::Base
named_scope :all
named_scope :published, :conditions => {:published => true}
named_scope :from_user, :conditions => {:kind => 'user'}
named_scope :from_admin, :conditions => {:kind => 'admin'}
end


Podemos resolver el problema de aplicar filtros combinados de la siguiente forma usando inject:

class PostsController < ApplicationController
def index
filter = (params[:filter] or String.new)
filter = filter.split(',').map(&:to_sym).select{|f| Post.scopes.include?(f)}
filter << :all

@posts = filter.inject(Post){|model, nscope| model.send(nscope)}
end
end

En primer lugar obtenemos la lista de named_scopes a aplicar y filtramos los no válidos, en segundo con inject se los aplicamos al modelo.

Con ese código tan simple podemos usar rutas del tipo:

http://server/posts
http://server/posts?filter=published
http://server/posts?filter=published,from_user

2 comentarios:

Unknown dijo...

Probado, funciona y queda limpio

Mil gracias

javiyu dijo...

De nada ;)