Ruby on Rails
Thursday, July 2, 2015
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:
-- 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 doresources :commentsmember doget 'rankup'get 'rankdown'endend
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.saveredirect_to articles_pathenddef 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.saveredirect_to articles_pathend
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_rankarticle.save@start_rank = @start_rank + 1
end@article.destroyredirect_to articles_pathend
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 rubyonrails-talk+unsubscribe@googlegroups.com.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
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.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment