Had a little fun with acts_like_list... Build in Rails 3, should work in Rails 4 though???
Add to your gem file:
gem 'acts_as_list'
Run:
bundle install
Add the field position as an integer to your Articles table:
From rails console:
RUN: rails g migration AddPositionToArticle position:integer
RUN: rake db:migrate
You could go to your database to verify
mysql> describe articles;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| article | varchar(255) | YES | | NULL | |
| rank | int(11) | YES | | NULL | |
| position | int(11) | YES | | NULL | |
+------------+--------------+------+-----+---------+----------------+
Go to your Article model:
class Article < ActiveRecord::Base
attr_accessible :article, :rank, :position
acts_as_list
before_save :position_to_rank
## Just populating rank .... eventually you can delete it, at view level you can use the work Rank if you are more comfortable with that
def position_to_rank
self.rank = self.position
end
end
Your Articles controller:
class ArticlesController < ApplicationController
def index
@articles = Article.order("position")
end
def rank
@art = Article.find(params[:id])
process = params[:process]
if process == "Move Up"
@art.move_higher
elsif process == "Move Down"
@art.move_lower
elsif process == "Move Bottom"
@art.move_to_bottom
elsif process == "Move Top"
@art.move_to_top
elsif process == "Insert At"
@art.insert_at(params[:id].to_i - 1)
end
redirect_to :action => :index
end
def show
@article = Article.find(params[:id]) unless params[:id].blank?
end
def new
@article = Article.new
end
def create
## Didn't test this, obviously no error management
@article = Article.new(params[:article]) unless params[:article].blank?
if @article.save
redirect_to @article, :notice => "Successfully created article."
else
render :action => 'new'
end
end
def edit
## Didn't test this, obviously no error management
@article = Article.find(params[:id]) unless params[:id].blank?
end
def update
## Didn't test this, obviously no error management
@article = Article.find(params[:id]) unless params[:id].blank?
if @article.update_attributes(params[:article])
redirect_to @article, :notice => "Successfully updated article."
else
render :action => 'edit'
end
end
def destroy
## Didn't test this, obviously no error management
@article = Article.find(params[:id]) unless params[:id].blank?
@article.destroy
redirect_to articles_url, :notice => "Successfully destroyed article."
end
end
Go to your router and verify or add:
resources :articles
match 'articles/rank/(:id)/(:process)' => "articles#rank", :as => :articles_rank
Your views in article(s) folder:
index.html.erb
<% "Articles" %>
<table >
<% for article in @articles %>
<tr>
<%= content_tag_for :td, article do %> ## Probably not necessary
<td> <%= link_to "Move Up", articles_rank_url(
article.id, "Move Up") %></td>
<td> <%= link_to "Move Down", articles_rank_url(
article.id, "Move Down") %></td>
<td> <%= link_to "Move Top", articles_rank_url(
article.id, "Move Top") %> </td>
<td> <%= link_to "Move Bottom", articles_rank_url(
article.id, "Move Bottom") %></td>
<td> <%= link_to article.id.to_i, articles_rank_url(
article.id, "Insert At") %></td>
<td> <%= article.article %></td>
<td> <%= "Position " + article.position.to_s %> </td>
<td> <%= "Rank " + article.rank.to_s %> </td>
<td> <%= link_to "Show", article %></td>
<td> <%= link_to "Edit", edit_article_url(
article.id) %> </td>
<td> <%= link_to "Destroy", article, {:confirm => 'Are you sure?', :method => :delete} %></td>
<% end %>
</tr>
<% end %>
</table>
<p><%= link_to "New Article", new_article_path, {:class=>"search"} %></p>
edit.html.erb
<%= "Edit Article" %>
<%= render 'form' %>
<p>
<%= link_to "Show", @article %> |
<%= link_to "View All", articles_path %>
</p>
_form.html.erb
<%= form_for @article do |f| %>
<% if @article.errors.any? %>
<% end %>
<p>
<%= f.label :article %><br />
<%= f.text_field :article %>
</p>
<p><%= f.submit %></p>
<% end %>
new.html.erb
<%= "New Article" %>
<%= render 'form' %>
<p><%= link_to "Back to List", articles_path %></p>
show.html.erb
<%= "Article" %>
<p>
<strong>Article:</strong>
<%= @article.article %>
</p>
<p>
<strong>postion:</strong>
<%= @article.position %>
</p>
<p>
<%= link_to "Edit", edit_article_path(@article) %> |
<%= link_to "Destroy", @article, {:confirm => 'Are you sure?', :method => :delete} %> |
<%= link_to "View All", articles_path %>
</p>
That's about it! Hope it works for you!
The api (rails 4) source is :
https://github.com/swanandp/acts_as_list