Skip to content

Commit

Permalink
lots of work to improve nested resource support
Browse files Browse the repository at this point in the history
  • Loading branch information
jnewland committed Mar 3, 2008
1 parent 0f80f8e commit 5f3af15
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 34 deletions.
Empty file removed TODO
Empty file.
89 changes: 62 additions & 27 deletions lib/resource_this.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,26 @@ def resource_this(options = {})
class_name = options[:class_name] || singular_name.camelize
plural_name = singular_name.pluralize
will_paginate_index = options[:will_paginate] || false
url_string = "#{singular_name}_url(@#{singular_name})"
list_url_string = "#{plural_name}_url"
finder_base = class_name
resource_url = "#{singular_name}_url(@#{singular_name})"
collection_url = "#{plural_name}_url"
resource_url = options[:path_prefix] + resource_url unless options[:path_prefix].nil?
collection_url = options[:path_prefix] + collection_url unless options[:path_prefix].nil?

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
url_string = "#{nested}_#{singular_name}_url(" + [nested, singular_name].map { |route| "@#{route}"}.join(', ') + ')'
list_url_string = "#{nested}_#{plural_name}_url(@#{nested})"
finder_base = "@#{nested}.#{plural_name}"
nested = options[:nested].to_s.singularize
nested_class = nested.camelize
nested_resource_url = "#{nested}_#{singular_name}_url(" + [nested, singular_name].map { |route| "@#{route}"}.join(', ') + ')'
nested_collection_url = "#{nested}_#{plural_name}_url(@#{nested})"
nested_resource_url = options[:path_prefix] + nested_resource_url unless options[:path_prefix].nil?
nested_collection_url = options[:path_prefix] + nested_collection_url unless options[:path_prefix].nil?
module_eval <<-"end_eval", __FILE__, __LINE__
before_filter :load_#{nested}
end_eval
end

#process path_prefix
url_string = options[:path_prefix] + url_string unless options[:path_prefix].nil?
list_url_string = options[:path_prefix] + list_url_string unless options[:path_prefix].nil?


#standard before_filters
module_eval <<-"end_eval", __FILE__, __LINE__
before_filter :load_#{singular_name}, :only => [ :show, :edit, :update, :destroy ]
Expand All @@ -42,29 +40,69 @@ def resource_this(options = {})
before_filter :create_#{singular_name}, :only => [ :create ]
before_filter :update_#{singular_name}, :only => [ :update ]
before_filter :destroy_#{singular_name}, :only => [ :destroy ]
protected
def finder_options
resource_this_finder_options.class == Proc ? resource_this_finder_options.call : {}
end
end_eval

unless options[:nested].nil?
if options[:nested].nil?
module_eval <<-"end_eval", __FILE__, __LINE__
def finder_base
#{class_name}
end
def collection
#{class_name}.find(:all, finder_options)
end
def collection_url
#{collection_url}
end
def resource_url
#{resource_url}
end
end_eval
else
module_eval <<-"end_eval", __FILE__, __LINE__
def load_#{nested}
@#{nested} = #{nested_class}.find(params[:#{nested}_id])
@#{nested} = #{nested_class}.find(params[:#{nested}_id]) rescue nil
end
def finder_base
@#{nested}.nil? ? #{class_name} : @#{nested}.#{plural_name}
end
def collection
@#{nested}.nil? ? #{class_name}.find(:all, finder_options) : @#{nested}.#{plural_name}.find(:all, finder_options)
end
def collection_url
@#{nested}.nil? ? #{collection_url} : #{nested_collection_url}
end
def resource_url
@#{nested}.nil? ? #{resource_url} : #{nested_resource_url}
end
end_eval
end

module_eval <<-"end_eval", __FILE__, __LINE__
def load_#{singular_name}
@#{singular_name} = #{finder_base}.find(params[:id])
@#{singular_name} = finder_base.find(params[:id])
end
def new_#{singular_name}
@#{singular_name} = #{finder_base}.new
@#{singular_name} = finder_base.new
end
def create_#{singular_name}
returning true do
@#{singular_name} = #{finder_base}.new(params[:#{singular_name}])
@#{singular_name} = finder_base.new(params[:#{singular_name}])
@created = @#{singular_name}.save
end
end
Expand All @@ -80,19 +118,16 @@ def destroy_#{singular_name}
end
end_eval

#TODO: add sorting customizable by subclassed controllers
if will_paginate_index
module_eval <<-"end_eval", __FILE__, __LINE__
def load_#{plural_name}
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]))
@#{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}
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)
@#{plural_name} = collection
end
end_eval
end
Expand Down Expand Up @@ -127,8 +162,8 @@ def create
respond_to do |format|
if @created
flash[:notice] = '#{class_name} was successfully created.'
format.html { redirect_to #{url_string} }
format.xml { render :xml => @#{singular_name}, :status => :created, :location => #{url_string} }
format.html { redirect_to(resource_url) }
format.xml { render :xml => @#{singular_name}, :status => :created, :location => resource_url }
format.js
else
format.html { render :action => :edit }
Expand All @@ -149,7 +184,7 @@ def update
respond_to do |format|
if @updated
flash[:notice] = '#{class_name} was successfully updated.'
format.html { redirect_to #{url_string} }
format.html { redirect_to(resource_url) }
format.xml { head :ok }
format.js
else
Expand All @@ -162,7 +197,7 @@ def update
def destroy
respond_to do |format|
format.html { redirect_to #{list_url_string} }
format.html { redirect_to(collection_url) }
format.xml { head :ok }
format.js
end
Expand Down
54 changes: 50 additions & 4 deletions test/resource_this_netsting_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ def setup
@request.accept = 'application/xml'
@response = ActionController::TestResponse.new
@first = Post.create(:title => "test", :body => "test")
@second = Post.create(:title => "test2", :body => "test2")
@first_comment = Comment.create(:post => @first, :body => "test")
@second_comment = Comment.create(:post => @second, :body => "test")
ActionController::Routing::Routes.draw do |map|
map.resources :posts do |post|
post.resources :comments
end
map.resources :comments
end
end

Expand All @@ -23,8 +26,15 @@ def teardown
def test_should_get_index
get :index, :post_id => @first.id
assert_response :success
assert assigns(:comments)
assert assigns(:post)
assert_equal @first.comments, assigns(:comments)
assert_equal @first, assigns(:post)
end

def test_should_get_index_without_post
get :index
assert_response :success
assert assigns(:post).nil?
assert_equal Comment.find(:all), assigns(:comments)
end

def test_should_get_new
Expand All @@ -34,9 +44,16 @@ def test_should_get_new
assert assigns(:post)
end

def test_should_get_new_without_post
get :new
assert_response :success
assert assigns(:post).nil?
assert assigns(:comment)
end

def test_should_create_comment
assert_difference('Comment.count') do
post :create, :post_id => @first.id, :post => { :body => "test" }
post :create, :post_id => @first.id, :comment => { :body => "test" }
end
assert_response :created
assert assigns(:comment)
Expand All @@ -46,18 +63,33 @@ def test_should_create_comment
def test_should_create_comment_html
@request.accept = 'text/html'
assert_difference('Comment.count') do
post :create, :post_id => @first.id, :post => { :body => "test" }
post :create, :post_id => @first.id, :comment => { :body => "test" }
end
assert_redirected_to "posts/#{assigns(:post).id}/comments/#{assigns(:comment).id}"
end

def test_should_create_comment_html_without_post
@request.accept = 'text/html'
assert_difference('Comment.count') do
post :create, :comment => { :body => "test" }
end
assert_redirected_to "/comments/#{assigns(:comment).id}"
end

def test_should_show_comment
get :show, :post_id => @first.id, :id => @first_comment.id
assert_response :success
assert assigns(:comment)
assert assigns(:post)
end

def test_should_show_comment_without_post
get :show, :id => @first_comment.id
assert_response :success
assert_equal Comment.find(@first_comment.id), assigns(:comment)
assert assigns(:post).nil?
end

def test_should_update_comment
put :update, :post_id => @first.id, :id => @first_comment.id, :comment => { :post => @first, :body => "test" }
assert_response :success
Expand All @@ -71,6 +103,12 @@ def test_should_update_comment_html
assert_redirected_to "posts/#{assigns(:post).id}/comments/#{assigns(:comment).id}"
end

def test_should_update_comment_html_without_post
@request.accept = 'text/html'
put :update, :id => @first_comment.id, :comment => { :post => @first, :body => "test2" }
assert_redirected_to "/comments/#{assigns(:comment).id}"
end

def test_should_destroy_comment
assert_difference('Comment.count', -1) do
delete :destroy, :post_id => @first.id, :id => @first_comment.id
Expand All @@ -85,4 +123,12 @@ def test_should_destroy_html
end
assert_redirected_to "posts/#{assigns(:post).id}/comments"
end

def test_should_destroy_html_without_post
@request.accept = 'text/html'
assert_difference('Comment.count', -1) do
delete :destroy, :id => @first_comment.id
end
assert_redirected_to "/comments"
end
end
4 changes: 2 additions & 2 deletions test/resource_this_sorting_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ def test_should_get_index
assert_equal @a, assigns(:widgets).first
end

def test_should_get_index_sorted
@controller.resource_this_finder_options = {:order => 'body'}
def test_should_get_index_sorted_with_inline_proc
@controller.resource_this_finder_options = Proc.new { { :order => 'body' } }
get :index
assert_response :success
assert assigns(:widgets)
Expand Down
3 changes: 2 additions & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
RAILS_ROOT = '.' unless defined? RAILS_ROOT
RAILS_ENV = 'test' unless defined? RAILS_ENV


ActiveRecord::Base.logger = Logger.new(STDOUT) if ENV['DEBUG']
ActionController::Base.logger = Logger.new(STDOUT) if ENV['DEBUG']

ActionController::Base.send :include, ResourceThis

Expand Down

0 comments on commit 5f3af15

Please sign in to comment.