Intro
If you have models with belongs_to and has_many relationships and have used the children view hint on the parent model, you will get a collection of cards on the bottom of the main page or on the sidebar depending on how many child models you specify and in what order. See (http://cookbook.hobocentral.net/manual/viewhints#child_relationships) for more information on this behavior.
You may have noticed, however, that automatic pagination does not happen. :-(
It would be nice if the children viewhint supported parameters that would enable this. Maybe the author of the generator spitting out the Rapid show page is reading this…heck, I might try a hack of it myself.
But until then, there are two ways to support this behavior. This recipe documents them.
Prerequisites
Create a demo app.
$ hobo paginate_children
Create models
Let’s create models that support parent/children relationships. How about Post and Comment?
$ cd paginate_children
$ ruby script/generate hobo_model_resource Post name:string
$ ruby script/generate hobo_model_resource Comment name:string
Edit the models to define the parent/child relationship.
paginate_children/app/models/post.rb
class Post < ActiveRecord::Base
hobo_model # Don't put anything above this
fields do
name :string
timestamps
end
+ has_many :comments
# --- Permissions --- #
def create_permitted?
acting_user.administrator?
end
def update_permitted?
acting_user.administrator?
end
def destroy_permitted?
acting_user.administrator?
end
def view_permitted?(field)
true
end
end
paginate_children/app/models/comment.rb
class Comment < ActiveRecord::Base
hobo_model # Don't put anything above this
fields do
name :string
timestamps
end
+ belongs_to :post
# --- Permissions --- #
def create_permitted?
acting_user.administrator?
end
def update_permitted?
acting_user.administrator?
end
def destroy_permitted?
acting_user.administrator?
end
def view_permitted?(field)
true
end
end
Add children viewhint
paginate_children/app/viewhints/post_hints.rb
Add the viewhint for comments to the post model.
class PostHints < Hobo::ViewHints
# model_name "My Model"
# field_names :field1 => "First Field", :field2 => "Second Field"
# field_help :field1 => "Enter what you want in this field"
# children :primary_collection1, :aside_collection1, :aside_collection2
+ children :comments
end
Overriding will_paginate default per_page value
In order for us to be able to see pagination work with only a few child entries, use this monkey patch to change the default per_page value from 30 to 3. Add this code to the end of paginate_children/config/environment.rb:
# Set will_paginate default per_page to 15 instead of the default 30
ActiveRecord::Base.instance_eval do
def per_page; 3; end
end
Startup
Migrate your models and startup the server.
$ ruby script/generate hobo_migration
...
$ ruby script/server
At this point, you should be able to add the administrative user. Go ahead also and add a post and add 4 comments attached to that post.
Two techniques
There are two techniques to achieve this.
- You create a paginated collection instance variable in the post controller and then override the show page to use this variable. You also have to add the paginate tags so the pager controls show.
- Use the index owner action on the comment controller.
Collection instance variable
We need to set up pagination for the comments collection. Add a comments instance variable to the posts_controller.
paginate_children/app/controllers/posts_controller.rb
class PostsController < ApplicationController
hobo_model_controller
auto_actions :all
+ def show
+ hobo_show do
+ @comments = this.comments.paginate(:page => params[:page])
+ end
+ end
end
Next, override the comments collection in the Post show page to use the instance variable just created and add the paginate tags.
paginate_children/app/views/taglibs/application.dryml
<include src="rapid" plugin="hobo"/>
<include src="taglibs/auto/rapid/cards"/>
<include src="taglibs/auto/rapid/pages"/>
<include src="taglibs/auto/rapid/forms"/>
<set-theme name="clean"/>
<def tag="app-name">Paginate Children</def>
+<extend tag="show-page" for="Post">
+ <old-show-page merge>
+ <collection: replace>
+ <page-nav with="&@comments" param="top-page-nav"/>
+ <collection with="&@comments" />
+ <page-nav with="&@comments" param="bottom-page-nav"/>
+ </collection>
+ </old-show-page>
+</extend>
Test it out
If you added 4 or more comments to a post, that post’s show page should show those comments paginated with 3 entries per page.
Index owner action
You can get pagination behavior out of the box by using the index owner action on the comment controller as defined below.
paginate_children/app/controllers/comments_controller.rb
class CommentsController < ApplicationController
hobo_model_controller
auto_actions :all
+ auto_actions_for :post, [:index]
end
You can the use the url http://localhost:3000/posts/:id/comments to access the show page for the post id referenced by :id. The comments collection will be paginated (and note that this is not because of the code from technique 1…see app/views/taglibs/auto/rapid/pages.dryml and look for index-for-post-page). The problem with this technique (unless I am missing something) is that the wiring up of the navigation to this url is not done by the framework automatically.
User contributed notes
-
On June 30, 2011 ylluminate said:
Did this ever get integrated?
On July 30, 2010 Owen said:
Sweet! thanks for that.-Owen