It would be nice to allow our readers to leave a little feedback, so in this edition we’ll do just that. This should give you insight into how Hobo can present one-to-many relationships. Create a very simple model with the following:
$ script/generate hobo_model_resource comment body:text
Nothing you haven’t seen. Open app/models/comment.rb and alter it to be like this:
class Comment < ActiveRecord::Base
hobo_model # Don't put anything above this
fields do
body :text
timestamps
end
belongs_to :user, :creator => true
belongs_to :entry
# --- Permissions --- #
def create_permitted?
acting_user.signed_up?
end
def update_permitted?
acting_user.administrator?
end
def destroy_permitted?
acting_user.administrator?
end
def view_permitted?(field)
true
end
end
A few changes to note here. We’ve added two relations, one to the User model and another to the Entry model. The :creator flag automatically sets the user if one is not given. You should also note the change to the permissions. Any user that has signed up will be able to create new comments. Let’s add the relations to the Entry model. Put these lines after the fields in app/models/entry.rb:
belongs_to :user, :creator => true
has_many :comments, :dependent => :destroy
The relation to comments has been made and now each entry will have an author. Now for the User model. Add these lines to app/models/user.rb after the fields:
has_many :entries
has_many :comments
Go ahead and run a hobo_migration to apply the changes to the database.
$ script/generate hobo_migration
If you take a look at the blog now, you’ll find a very awkward setup. Comments can only be created from the Comments tab. Comments aren’t connected to entries in an obvious way. Let’s change that. First, open up app/viewhints/entry_hints.rb and add this before the final end:
children :comments
Comments related to an entry are now shown on the entry’s show page. Let’s make it so users can add comments from there as well. Open app/controllers/comments_controller.rb and change it to be like this:
class CommentsController < ApplicationController
hobo_model_controller
auto_actions :destroy
auto_actions_for :entry, [:create]
end
The auto_actions are now limited to destroy, which will allow the administrators to easily remove comments. The auto_actions_for is very convenient. That one line allows users to make comments from the show page of an entry. Take a look. One problem you should notice is that the user relation is accessible. Users would be able to leave comments as anyone on the site. That’s no good. Open app/views/taglibs/application.dryml and append this to the end of it:
<extend tag="card" for="Comment">
<old-card merge>
<body:>
<div>
On <view:created_at/>, <a:user/> said:
</div>
<view:body/>
</body:>
</old-card>
</extend>
<extend tag="form" for="Comment">
<old-form merge>
<field-list: fields="body" without-body-label/>
</old-form>
</extend>
We’ve made a prettier card for comments and the form has been trimmed to only display a field for body. Of course, that’s not enough to stop users from spoofing comments. Open app/controllers/comments_controller.rb and add this before the final end:
def create_for_entry
# Remove user spoofing
# Hobo should make this easier
params["comment"].delete("user_id")
hobo_create
end
Yep. Hobo allows you customize how controllers on related pages work. All that we’ve done is removed user_id from the params. Hobo will instead relate the comment to the creator as we defined earlier. You might consider doing something similar to this for entries as well. Since comments are related to users and entries are now related to users, let’s make the user show page more interesting. Create a new file at app/viewhints/user_hints.rb and add this content:
class UserHints < Hobo::ViewHints
children :entries, :comments
end
The user show page now features entries and comments authored by the user. Your extra credit on this lesson is to make the card for Entry more presentable.