Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

sorting

git-svn-id: http://jnewland.com/svn/public/ruby/rails/plugins/resource_this@43 9b6b69f6-dd27-0410-8144-a0f3c56a22ea
  • Loading branch information...
commit 456fa6eaf9925653336b1608bd6132e0f7d2d52c 1 parent 93a28c0
jnewland authored
View
44 README
@@ -118,7 +118,8 @@ Not scaffolding. Resourcing. Creates extremely customizable resource controllers
end
end
-Nested resources like so:
+Nested Resources
+===========
class CommentsController < ActionController::Base
resource_this :nested => [:posts]
@@ -132,8 +133,49 @@ This generates a very similar controller to the one above with adjusted redirect
@post = Post.find(params[:post_id])
end
+Sorting, etc
+===========
+
+ class CommentsController < ActionController::Base
+ resource_this :finder_options => {:order => 'created_on'}
+ end
+
+...or, for lazily evaluated sorting options:
+
+ class CommentsController < ActionController::Base
+ resource_this :finder_options => Proc.new { finder_options }
+
+ protected
+
+ def finder_options
+ order = case params[:sort]
+ when 'date_reverse' then 'created_on desc'
+ else 'created_on'
+ end
+ {:order => order, :limit => params[:limit] || 10 }
+ end
+
+ end
+
+will_paginate
+===========
+
+will_paginate support is baked right in:
+
+ class CommentsController < ActionController::Base
+ resource_this :will_paginate => true
+ end
+
+This works with the :finder_options option as well
+
+Opinionated Software
+===========
+
The separation of logic - DB operations in before_filters, rendering in the standard resource controller methods - makes this approach ridiculously easy to customize. Need to load an additional object for the :show action? Slap another before_filter on it. Need to change the path that the :update action redirects to? Override the :update action with your new rendering behavior.
+Generator
+===========
+
A resource_this generator is included - does the same thing as the 'resource' generator but adds 'resource_this' to the generated controller.
Questions? Comments? Flames? Patches?
View
2  TODO
@@ -1,2 +0,0 @@
-* Document will_paginate support.
-* Add logical sorting support to the :index action.
View
11 lib/resource_this.rb
@@ -5,7 +5,7 @@ def self.included(base)
module ClassMethods
def resource_this(options = {})
- options.assert_valid_keys(:class_name, :will_paginate, :sort_method, :nested, :path_prefix)
+ options.assert_valid_keys(:class_name, :will_paginate, :finder_options, :nested, :path_prefix)
singular_name = controller_name.singularize
singular_name = options[:class_name].downcase.singularize unless options[:class_name].nil?
@@ -16,6 +16,9 @@ def resource_this(options = {})
list_url_string = "#{plural_name}_url"
finder_base = class_name
+ class_inheritable_accessor :resource_this_finder_options
+ self.resource_this_finder_options = options[:finder_options] || {}
+
unless options[:nested].nil?
nested = options[:nested].to_s.singularize
nested_class = nested.camelize
@@ -81,13 +84,15 @@ def destroy_#{singular_name}
if will_paginate_index
module_eval <<-"end_eval", __FILE__, __LINE__
def load_#{plural_name}
- @#{plural_name} = #{finder_base}.paginate(:page => params[:page])
+ finder_options = resource_this_finder_options.class == Proc ? resource_this_finder_options.call : resource_this_finder_options
+ @#{plural_name} = #{finder_base}.paginate(finder_options.merge(:page => params[:page]))
end
end_eval
else
module_eval <<-"end_eval", __FILE__, __LINE__
def load_#{plural_name}
- @#{plural_name} = #{finder_base}.find(:all)
+ finder_options = resource_this_finder_options.class == Proc ? resource_this_finder_options.call : resource_this_finder_options
+ @#{plural_name} = #{finder_base}.find(:all, finder_options)
end
end_eval
end
View
53 test/resource_this_sorting_test.rb
@@ -0,0 +1,53 @@
+require File.join(File.dirname(__FILE__), 'test_helper')
+
+class ResourceThisSortingTest < Test::Unit::TestCase
+ def setup
+ @controller = WidgetsController.new
+ @request = ActionController::TestRequest.new
+ @request.accept = 'application/xml'
+ @response = ActionController::TestResponse.new
+ @a = Widget.create(:title => "aaa", :body => "zzz")
+ @z = Widget.create(:title => "zzz", :body => "aaa")
+ 100.times do
+ Widget.create(:title => "foo", :body => "bar")
+ end
+ with_routing do |set|
+ set.draw do |map|
+ map.resources :widgets
+ end
+ end
+ end
+
+ def teardown
+ Widget.find(:all).each { |w| w.destroy }
+ end
+
+ def test_should_get_index
+ get :index
+ assert_response :success
+ assert assigns(:widgets)
+ assert_equal @a, assigns(:widgets).first
+ end
+
+ def test_should_get_index_sorted
+ @controller.resource_this_finder_options = {:order => 'body'}
+ get :index
+ assert_response :success
+ assert assigns(:widgets)
+ assert_equal @z, assigns(:widgets).first
+ end
+
+ def test_should_get_index_sorted_with_proc
+ @controller.resource_this_finder_options = Proc.new { finder_options }
+ get :index
+ assert_response :success
+ assert assigns(:widgets)
+ assert_equal 2, assigns(:widgets).size
+ assert_equal @z, assigns(:widgets).first
+ end
+
+ def finder_options
+ {:order => 'body', :limit => 2}
+ end
+
+end
View
17 test/test_helper.rb
@@ -1,6 +1,6 @@
require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb'))
require 'action_controller/test_process'
-require 'active_record/fixtures'
+require 'test/unit'
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
@@ -17,6 +17,12 @@
t.column :created_at, :datetime
t.column :updated_at, :datetime
end
+ create_table :widgets do |t|
+ t.column :title, :string
+ t.column :body, :text
+ t.column :created_at, :datetime
+ t.column :updated_at, :datetime
+ end
end
class Post < ActiveRecord::Base
@@ -33,10 +39,19 @@ def validate
validates_associated :post
end
+class Widget < ActiveRecord::Base
+ def validate
+ end
+end
+
class PostsController < ActionController::Base
resource_this
end
+class WidgetsController < ActionController::Base
+ resource_this
+end
+
module Admin; end
class Admin::PostsController < ActionController::Base
Please sign in to comment.
Something went wrong with that request. Please try again.