will_paginate

will_paginate为Rails提供了非常方便的分页浏览功能。我们将通过一个小例子来展示:

1. 创建工程:

$rails test_will_paginate
$cd test_will_paginate

2. 安装插件:

$script/plugin install svn://errtheblog.com/svn/plugins/will_paginate

3. 生成post模型,并添加测试数据:

$script/generate scaffold post title:string body:text
#db/migrate/001_create_posts.rb
(1..50).each do |num|
  Post.create(:title => "title#{num}", :body => "body#{num}")
end

4. 生成数据表:

$rake db:migrate

5. 定义模型默认一页显示的条目数:

#app/models/post.rb
def self.per_page
  10
end

6. 修改controller的index方法,使其支持分页:

#app/controllers/posts_controller.rb
def index
  @posts = Post.paginate :page => params[:page], :order => 'updated_at DESC'
  ......
end

7. 调整页面显示:

#app/views/posts/index.html.erb
<%= will_paginate @posts %>

Total entries: <%= @posts.total_entries %>, total pages: <%= @posts.page_count %>, current page: <%= @posts.current_page %>

8. 最后加上will_paginate推荐的css:

#public/stylesheets/scaffold.css
.pagination {
  padding: 3px;
  margin: 3px;
}
.pagination a {
  padding: 2px 5px 2px 5px;
  margin: 2px;
  border: 1px solid #aaaadd;
  text-decoration: none;
  color: #000099;
}
.pagination a:hover, .pagination a:active {
  border: 1px solid #000099;
  color: #000;
}
.pagination span.current {
  padding: 2px 5px 2px 5px;
  margin: 2px;
  border: 1px solid #000099;
  font-weight: bold;
  background-color: #000099;
  color: #FFF;
}
.pagination span.disabled {
  padding: 2px 5px 2px 5px;
  margin: 2px;
  border: 1px solid #eee;
  color: #ddd;
}

Posted in  rails plugins


acts_as_rateable

acts_as_rateable插件为ActiveRecord模型对象提供评分/评级的能力,我们的示例是在blog系统中添加简单的打分功能。

1. 创建测试工程:

$rails test_acts_as_rateable
$cd test_acts_as_rateable

2. 安装插件:

$script/plugin install svn://rubyforge.org/var/svn/rateableplugin/trunk

3. 生成blog模型,并添加测试数据:

$script/generate scaffold blog name:string content:text
#db/migrate/001_create_blogs.rb
Blog.create(:name => "poorest", :content => "poorest")
Blog.create(:name => "poorer", :content => "poorer")
Blog.create(:name => "just so so", :content => "just so so")
Blog.create(:name => "better", :content => "better")
Blog.create(:name => "sbest", :content => "best")

4. 生成rating migration:

$script/generate migration add_ratings
#db/migrate/002_create_ratings.rb
def self.up
  create_table :ratings do |t|
    t.integer :rating    # You can add a default value here if you wish
    t.integer :rateable_id :null => false
    t.string :rateable_type, :null => false
  end
  add_index :ratings, [:rateable_id, :rating]    # Not required, but should help more than it hurts
end

def self.down
  drop_table :ratings
end

5. 生成数据表:

$rake db:migrate

6. 为blog模型增加打分功能:

#app/models/blog.rb
acts_as_rateable

7. 增加打分url:

#config/routes.rb
map.resources :blogs, :member => { :rating = :post }

8. 页面中增加打分form:

#app/views/blogs/show.html.erb
<% form_tag rating_blog_path(@blog) do %>
  Rating
  <% (1..5).each do |value| %>
    <%= radio_button_tag :rating, value, true %> <%= value %>
  <% end %>

  <%= submit_tag 'Rate' %>
<% end %>

9. controller中增加相应的action处理:

#app/controllers/blogs_controller.rb
def rating
  Blog.find(params[:id]).rating = params[:rating]
  redirect_to :action => :index
end

10. index页面显示打分结果:

#app/views/blogs/index.html.erb
Rating
<%=h blog.rating %>

11. 增加搜索功能:

#app/views/blogs/index.html.erb
<% options = "12345" %>
<% form_tag blogs_path, :method => :get do %>
  Rating from <%= select_tag "from", options %> to <%= select_tag "to", options %>
  <%= submit_tag 'Search' %>
<% end %>
#app/controllers/blogs_controller.rb
def index
  if params[:from] and params[:to]
    @blogs = Blog.find_all_by_rating(params[:from].to_i..params[:to].to_i)
  else
    @blogs = Blog.find(:all)
  end

  respond_to do |format|
    format.html # index.html.erb
    format.xml  { render :xml => @blogs }
  end
end

Tips: 以上的示例只能为每个blog保留一个评分,如果希望能够多次评分,以获得平均分的话,可以在model中增加average参数:

#app/models/blog.rb
acts_as_rateable :average => true

不过这样的话,就不能用find_by_rating方法了。如果需要的话需要修改acts_as_rating.rb源码

Posted in  rails plugins


auto_complete

atuo_complete插件提供输入提示功能,我们通过一个example来示范,用户在输入日志的tag时,有自动输入提供。

  1. 创建测试工程:
$rails test_auto_complete
$cd test_auto_complete
  1. 生成blog和tag模型:
$script/generate scaffold blog title:string content:string
$script/generate model tag name:string blog_id:integer
  1. 映射一对多关系:
#app/models/blog.rb
has_many :tags
#app/models/tag.rb
belongs_to :blog
  1. 添加测试数据:
#db/migrate/001_create_blogs.rb
Blog.create(:title = test, :content = test)
#db/migrate/002_create_tags.rb
blog = blog.find(:first)
Tag.create(:name = ruby, :blog_id = blog)
Tag.create(:name = rails, :blog_id = blog)
Tag.create(:name = agile, :blog_id = blog)
Tag.create(:name = web, :blog_id = blog)
  1. 生成数据表:
$rake db:migrate
  1. 安装auto_complete插件:
$script/plugin install http://svn.rubyonrails.org/rails/plugins/auto_complete/
  1. 为controller添加auto_complete_for方法:
#app/controllers/blogs_controller.rb
auto_complete_for :tag, :name
  1. 在routes中添加映射关系:
#config/routes.rb
map.resources :blogs, :collection = { :auto_complete_for_tag_name = :get }
  1. 在view中添加需要提示功能的输入框:
#app/views/blogs/new.html.erb
Tags
<%= text_field_with_auto_complete :tag, :name, {}, {:method = :get} %>
  1. 确保页面已经包含prototype库:
#app/views/layout/blogs.html.erb
<%= javascript_include_tag :defaults %>
  1. 测试:
$script/server

在浏览器中输入http://localhost:3000/blogs/new 在Tags输入框中输入r,系统将提示ruby和rails

  1. 如果你想输入多个tag都有提示的话,比如用空格分开:
#app/views/blogs/new.html.erb
<%= text_field_with_auto_comlete :tag, :name, {}, {:method = :get, :token = ' '} %>

在Tags输入框中输入ruby on r,系统将提示ruby和rails

  1. 如果你想在光标进入输入框就提示的话,可以这样做:
#app/views/blogs/new.html.erb
<%= text_field_with_auto_complete :tag, :name, {:onfocus = tag_name_auto_completer.activate()}, {:method = :get, :token = ' '} %>

在Tags输入框为空时,点击该输入框,系统将提示agile, rails, ruby, web

Tips:

#Controller中可带参数有:conditions, :limit, :order
class BlogController  ApplicationController
  auto_complete_for :tag, :name, :limit = 15, :order = 'created_at DESC'
end
#View中可待参数有两种:
#一是tag_options,与text_field的options相同
#二是completion_options,与prototype库的Ajax.AutoCompleter的options相同
<%= text_field_with_auto_complete :tag, :name, {:size = 10}, {:tokens = ' '} %>

Posted in  rails plugins


Fork me on GitHub