Is your plugin hosted on GitHub? Make sure to press the "fetch" button next to the repository field to fetch your plugin's info from GitHub rather than typing it all in.
Repository
Name
Home Page
Short description NEWS: updated and betterer (Sept 07) make ActiveResource compliant controllers for your RESTful models in one line (including nested resources)
Description With resources_controller (http://svn.ardes.com/rails_plugins/resources_controller) you can quickly add an ActiveResource compliant controller for your your RESTful models. = Examples Here are some examples - for more on how to use RC go to the Usage section at the bottom, for syntax head to resources_controller_for ==== Example 1: Super simple usage Here's a simple example of how it works with a Forums has many Posts model: class ForumsController < ApplicationController resources_controller_for :forums end Your controller will get the standard CRUD actions, @forum will be set in member actions, @forums in index. ==== Example 2: Specifying enclosing resources class PostsController < ApplicationController resources_controller_for :posts, :in => :forum end As above, but the controller will load @forum on every action, and use @forum to find and create @posts ==== Wildcard enclosing resources All of the above examples will work for any routes that match what it specified PATH RESOURCES CONTROLLER WILL DO: Example 1 /forums @forums = Forum.find(:all) /users/2/forums @user = User.find(2) @forums = @user.forums.find(:all) Example 2 /posts @posts = Post.find(:all) /forums/2/posts @forum = Forum.find(2) @posts = @forum.posts.find(:all) /sites/4/forums/3/posts @site = Site.find(4) @forum = @site.forums.find(3) @posts = @forum.posts.find(:all) /users/2/posts/1 This won't work as the controller specified that :posts are :in => :forum It is up to you which routes to open to the controller (in config/routes.rb). When you do, RC will use the route segments to drill down to the specified resource. This means that if User 3 does not have Post 5, then /users/3/posts/5 will raise a RecordNotFound Error. You dont' have to write any extra code to do this oft repeated controller pattern. With RC, your route specification flows through to the controller - no need to repeat yourself. If you don't want to have RC match wildcard resources just pass :load_enclosing => false resources_controller_for :posts, :in => :forum, :load_enclosing => 'false' ==== Example 3: Singleton resource Here's an example of a singleton, the account pattern that is so common. class AccountController < ApplicationController resources_controller_for :account, :class => User, :singleton => true do @current_user end end Your controller will use the block to find the resource. The @account will be assigned to @current_user ==== Example 4: Allowing PostsController to be used all over First thing to do is remove :in => :forum class PostsController < ApplicationController resources_controller_for :posts end This will now work for /users/2/posts. ==== Example 4 and a bit: Mapping non standard resources How about /account/posts? The account is found in a non standard way - RC won't be able to figure out how tofind it if it appears in the route. So we give it some help. (in PostsController) map_resource :account, :singleton => true, :class => User, :find => :current_user Now, if :account apears in any part of a route (for PostsController) it will be mapped to (in this case) the current_user method of teh PostsController. To make the :account mapping available to all, just chuck it in ApplicationController This will work for any resource which can't be inferred from its route segment name map_resource :peeps, :source => :users map_resource :posts, :class => BadlyNamedPostClass ==== Example 5: Singleton association Here's another singleton example - one where it corresponds to a has_one or belongs_to association class ImageController < ApplicationController resources_controller_for :image, :singleton => true end When invoked with /users/3/image RC will find @user, and use @user.image to find the resource, and @user.build_image, to create a new resource. ==== Putting it all together An exmaple app config/routes.rb: map.resource :account do |account| account.resource :image account.resources :posts end map.resources :users do |user| user.resource :image user.resources :posts end map.resources :forums do |forum| forum.resources :posts forum.resource :image end app/controllers: class ApplicationController < ActionController::Base map_resource :account, :singleton => true, :find => :current_user def current_user # get it from session or whatnot end class ForumsController < AplicationController resources_controller_for :forums end class PostsController < AplicationController resources_controller_for :posts end class UsersController < AplicationController resources_controller_for :users end class ImageController < AplicationController resources_controller_for :image, :singleton => true end class AccountController < ApplicationController resources_controller_for :account, :singleton => true, :find => :current_user end This is how the app will handle the following routes: PATH CONTROLLER WHICH WILL DO: /forums forums @forums = Forum.find(:all) /forums/2/posts posts @forum = Forum.find(2) @posts = @forum.forums.find(:all) /forums/2/image image @forum = Forum.find(2) @image = @forum.image /image /posts /users/2/posts/3 posts @user = User.find(2) @post = @user.posts.find(3) /users/2/image POST image @user = User.find(2) @image = @user.build_image(params[:image]) /account account @account = self.current_user /account/image image @account = self.current_user @image = @account.image /account/posts/3 PUT posts @account = self.current_user @post = @account.posts.find(3) @post.update_attributes(params[:post]) === Views Ok - so how do I write the views? For most cases, just in exactly the way you would expect to. RC sets the instance variables to what they should be. But, in some cases, you are going to have different variables set - for example /users/1/posts => @user, @posts /forums/2/posts => @forum, @posts Here are some options (all are appropriate for different circumstances): * test for the existence of @user or @forum in the view, and display it differently * have two different controllers UserPostsController and ForumPostsController, with different views (and direct the routes to them in routes.rb) * use enclosing_resource - which always refers to the... immediately enclosing resource. Using the last technique, you might write your posts index as follows (here assuming that both Forum and User have .name) Posts for <%= link_to enclosing_resource_path, "#{enclosing_resource_name.humanize}: #{enclosing_resource.name}" %> <%= render :partial => 'post', :collection => @posts %> Notice *enclosing_resource_name* - this will be something like 'user', or 'post'. Also *enclosing_resource_path* - in RC you get all of the named route helpers relativised to the current resource and enclosing_resource. See NamedRouteHelper for more details. This can useful when writing the _post partial: <%= post.name %> <%= link_to 'edit', edit_resource_path(tag) %> <%= link_to 'destroy', resource_path(tag), :method => :delete %> when viewed at /users/1/posts it will show Cool post edit delete ... when viewd at /forums/1/posts it will show Other post edit delete ... This is like polymorphic urls, except that RC will just use whatever enclosing resources are loaded to generate the urls/paths. = Usage To use RC, there are just three class methods on controller to learn. resources_controller_for , , <&block> ClassMethods#nested_in , , <&block> map_resource , , <&block> === Customising finding and creating If you want to implement something like query params you can override *find_resources*. If you want to change the way your new resources are created you can override *new_resource*. class PostsController < ApplicationController resources_controller_for :posts def find_resources resource_service.find :all, :order => params[:sort_by] end def new_resource returning resource_service.new(params[resource_name]) do |post| post.ip_address = request.remote_ip end end end In the same way, you can override *find_resource*. === Writing controller actions You can make use of RC internals to simplify your actions. Here's an example where you want to re-order an acts_as_list model. You define a class method on the model (say *order_by_ids* which takes and array of ids). You can then make use of *resource_service* (which makes use of awesome rails magic) to send correctly scoped messages to your models. Here's how to write an order action def order resource_service.order_by_ids["things_order"] end the route map.resources :things, :collection => {:order => :put} and the view can conatin a scriptaculous drag and drop with param name 'things_order' When this controller is invoked of /things the :order_by_ids message will be sent to the Thing class, when it's invoked by /foos/1/things, then :order_by_ids message will be send to Foo.find(1).things association
Description format RDoc MarkDown Textile
License Ruby's Rails' (MIT) GPL LGPL BSD Apache Artistic PublicDomain BSD-type Free-Trial Free-but-Restricted OpenSource Proprietary Shareware Source-available-proprietary Commercial
Category Assets Controllers Internationalization Misc. Enhancements Model Rails Engines Searching and Queries Security Statistics and Logs Testing View Extensions