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



On Sunday, June 28, 2015 at 2:51:57 PM UTC-4, Federicko wrote:
>
> Hi All,
>
> I am learning rails at the moment and have gone through one of the 
> tutorials on the rails website for creating a simple blog system.
> I have added some new features to it and it is working great.
> However, I would like to show someone my code and see if it is the right 
> or most efficient way of achieve this.
>
> This system is based on the blog system from the Getting Started with 
> Rails guide which can be found on 
> http://guides.rubyonrails.org/getting_started.html
>
> I simply added a rank up/rank down function to the blog system:
>
> First, in my routes.rb I added:
>
> resources :articles do
>     resources :comments
>     member do 
>       get 'rankup'
>       get 'rankdown'
>     end
>   end
>
> Then, in my controller I added two new actions:
>
> def rankup
>   @this_article = Article.find(params[:id])
>   @new_rank = @this_article.rank.to_i-1
>   @prev_article = Article.find_by(rank: @new_rank)
>
>   @prev_article.rank = @this_article.rank
>   @this_article.rank = @new_rank
>
>   @this_article.save
>   @prev_article.save
>   redirect_to articles_path
> end
>
> def rankdown
>   @this_article = Article.find(params[:id])
>     @new_rank = @this_article.rank.to_i+1
>   @next_article = Article.find_by(rank: @new_rank)
>
>   @next_article.rank = @this_article.rank
>   @this_article.rank = @new_rank
>
>     @this_article.save
>   @next_article.save
>   redirect_to articles_path
> end
>
> I also updated the destroy action to include a re ranking function:
>
> def destroy
>   @article = Article.find(params[:id])
>   @start_rank = @article.rank
>   @next_articles = Article.where(["rank > ?", @start_rank]).order('rank 
> ASC')
>
>     @next_articles.each do |article| 
>     article.rank = @start_rank
>     article.save
>
>     @start_rank = @start_rank + 1
>     end
>
>   @article.destroy
>   redirect_to articles_path
> end
>
> And in the view I simply added the links to the list:
>
> <% @articles.each.with_index do |article, index| %>
>     <tr>
>       <td><%= article.title %></td>
>       <td><%= article.text %></td>
>       <td><%= article.rank %></td>
>       <td><%= link_to 'View', article_path(article) %></td>
>       <td><%= link_to 'Edit', edit_article_path(article) %></td>
>       <td><%= link_to 'Delete', article_path(article), method: :delete, 
> data: {confirm: 'Are you sure?'} %></td>
>       <td>
>         <% if index != 0 %>
>           <%= link_to 'Up', rankup_article_path(article) %>
>         <% end %>
>       </td>
>       <td>
>         <% if index != @articles.count-1 %>
>           <%= link_to 'Down', rankdown_article_path(article) %>
>         <% end %>
>       </td>
>     </tr>
>   <% end %>
>
> As mentioned, I am new to RoR so I don't know if I'm doing this correctly 
> according the Rails convention but the code is working great so I'm happy 
> about that.
>
> If someone can review my code please and tell me what I can improve on, 
> that would be great.
>
> I'm also thinking there might be an existing gem or something that I can 
> install that will do the ranking for me automatically.
>
> Anyway, look forward to your feedbacks.
>
>
> Thanks in advance.
>

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rubyonrails-talk/2b45d407-ff12-4d71-b65b-534b6a1ba838%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to