Rails: ActsAsList - Herramienta para manipular posición de objetos en una lista
Publicado el Martes, 3 de abril de 2012La clase con esta necesidad específica debe tener una columna position
(posición) definida como Integer
en la tabla de base de datos mapeada.
Es bastante sencilla de usar, pueden agregar a su Gemfile
la gema:
gem 'acts_as_list'
Voy a mostrar un ejemplo bastante sencillo en Rails a efectos de explicar el concepto. Tenemos una aplicación Rails con dos modelos: Book y Bookshelf. Generamos los modelos correspondientes:
$ rails generate model Bookshelf name:string
$ rails generate model Book title:string author:string description:text position:integer bookshelf:references
Y mandamos a generar las tablas:
$ rake db:migrate
Editamos el código de app/models/bookshelf.rb para agregar el orden:
class Bookshelf < ActiveRecord::Base
has_many :books, :order => 'position'
end
Y el libro:
class Book < ActiveRecord::Base
belongs_to :book_shelf
acts_as_list :scope => :bookshelf
end
Hecho esto ya estamos en condiciones de tener una Bookshelf con una colección de libros, y manipular el orden de los libros dentro de esta colección a través del índice "position". Podemos probar el código en la consola de Rails con:
$ rails console
Empezamos por crear un bookshelf para guardar nuestros libros:
bookshelf = Bookshelf.new(:name => "My bookshelf")
Hecho esto, creamos algunos libros asignándoles nuestro objeto bookshelf:
> book1 = Book.new(:title => "1984", :author => "George Orwell", :description => "Dystopian future", :bookshelf => bookshelf)
> book2 = Book.new(:title => "A princess of Mars", :author => "Edgar Rice Burroughs", :description => "John Carter is in this book", :bookshelf => bookshelf)
> book3 = Book.new(:title => "Ready Player One", :author => "Ernest Cline", :description => "Online virtual world / videogame", :bookshelf => bookshelf)
> book4 = Book.new(:title => "Foundation", :author => "Isac Aasimov", :description => "Blow-your-mind-Sci-fi", :bookshelf => bookshelf)
Ya armada la estructura y guardada podemos ver que los libros tienen su posición según fueron siendo guardados:
> bookshelf.books
Book Load (0.3ms) SELECT "books".* FROM "books" WHERE "books"."bookshelf_id" = 1 ORDER BY position
=> [#,
#,
#,
#]
El cuarto libro por ejemplo, podemos moverlo a la primera posición, y tras recargar los objetos, vemos que automáticamente los demás libros sumarán una posición más:
> book4.position
=> 4
> book4.move_to_top #Mover a la primera posición
(0.1ms) begin transaction
SQL (0.3ms) UPDATE "books" SET position = (position + 1) WHERE ("books"."bookshelf_id" = 1 AND position < 4)
(0.3ms) UPDATE "books" SET "position" = 1, "updated_at" = '2012-04-03 02:47:55.303110' WHERE "books"."id" = 4
(105.5ms) commit transaction
=> true
> book4.position
=> 1
Podemos comprobar las posiciones de los demás libros:
book1.position
=> 2
> book2.position
=> 3
Y mover un libro al final de la lista:
> book2.move_to_bottom
(0.1ms) begin transaction
SQL (0.3ms) UPDATE "books" SET position = (position - 1) WHERE ("books"."bookshelf_id" = 1 AND position > 3)
Book Load (0.3ms) SELECT "books".* FROM "books" WHERE ("books"."bookshelf_id" = 1 AND id != 2) ORDER BY position DESC LIMIT 1
(0.3ms) UPDATE "books" SET "position" = 4, "updated_at" = '2012-04-03 02:50:13.740681' WHERE "books"."id" = 2
(107.7ms) commit transaction
=> true
> book2 = Book.find 2
Book Load (0.2ms) SELECT "books".* FROM "books" WHERE "books"."id" = ? LIMIT 1 [["id", 2]]
=> #
> book2.position
=> 4
Y la posición final de todos los libros quedó:
> bookshelf.books
Book Load (0.3ms) SELECT "books".* FROM "books" WHERE "books"."bookshelf_id" = 1 ORDER BY position
=> [#,
#,
#,
#]
Una herramienta bastante útil con otros métodos como move_higher
, move_lower
, y más que pueden leer en el código fuente. Si quieren leer más al respecto visiten acts_as_list.
No hay comentarios en este post
Feed de comentariosDejar un comentario