tags

17 views
Skip to first unread message

Mark Sobkowicz

unread,
Nov 16, 2010, 11:24:38 PM11/16/10
to Hobo Users
I'm trying to extend the "recipe" tutorial - I've gotten alot of help here. The next thing I'm trying to do is to add a "tags" model. I want them to behave like private categories. So there is a has_many through relationship between tags and recipes, and tags also belong to users. The problem is the view_permitted for Tags. If I set it to acting_user == user, a user cannot create a new tag - asking for the new tag view gives an error. If I make view_permitted always true, everyone can see everyone elses tags, which makes them just like categories.

I suspect there is a way to get a new view for tag that already belongs to a user, so I can leave the view_permitted set to the user, but I'm not sure what it is.


Mark

Peter Ehrlich

unread,
Nov 17, 2010, 1:05:01 AM11/17/10
to Hobo Users
It sounds like you need to set the tag to be owned by the user
initially, so that they can view it. You could add this to your field
defintion: :creator => true So it might look like:

belongs_to :creator, :class_name => "User", :creator => true

That creator feature is built into hobo. A pure rails way tow do it
would be to create a filter for before validation or before creation
and have it set the user.


If I'm reading this wrong and you can't even get to the new page, know
about this:
view permitted if:
acting_user == user || new_record?

--Peter

Mark Sobkowicz

unread,
Nov 17, 2010, 8:21:51 AM11/17/10
to hobo...@googlegroups.com
Thanks. That did the trick. So I added "tags" to the fieldlist for the edit page. Now I have a permissions problem. If I say:

def view_permitted?(field)
acting_user== creator

end

Tags do not show up on the edit page. If I put

def view_permitted?(field)
true
end

They do show up, but everyone's tags show up - not just the users own tags. Is there a way to change the permissions so that only the users' own tags show? Or a way to extend the form element tag so that it only shows the current users' tags?

Peter Ehrlich

unread,
Nov 17, 2010, 12:42:24 PM11/17/10
to Hobo Users
So I'm not sure which model you're pulling these permissions method
from, but at any rate it sounds like you need field-specific
permissions, if only tags are not showing. Perhaps something inspired
by this?

def view_permitted?(field)
return true if :tag == field and acting_user == tag.creator
end

Notice the use of a sym as the fieldname.

Mark Sobkowicz

unread,
Nov 17, 2010, 1:40:47 PM11/17/10
to Hobo Users
I can't get this to work.   Let me try to be more specific.   I have models Recipe, Tag, User, and TagAssignment.    

Recipe belongs to :creator, :class_name = "User"
Tag belongs to :creator, :class_name = "User"
Recipe has many Tags through TagAssignment (and vice-versa)

The page is the edit page of Recipe.   When I add "tags" to the field-list for the edit page, what I see depends on what is in the view_permitted? of Tag.  If this returns true, I see the neat popupmenu with a list of tags and buttons to delete the tags.  But it shows everyones tags. 

   If I put the suggested code in the view_permitted, the popup doesn't show up at all.

I've been looking at the definition of the <select-many> tag.   Since it has the line
options ||= this_field_reflection.klass.all(:conditions =>this.conditions).select {|x| can_view?(x)}
I figured can_view?(x) means by default it checks view_permitted for each of its collection, but that is not what seems to happen.     Could I put a selector in the show controller for recipe?

Or could I modify <select-many> to change which items it will show?

kevinpfromnm

unread,
Nov 17, 2010, 2:47:21 PM11/17/10
to Hobo Users
Not that it should be any different in effect, but try:

def view_permitted?(field)
creator_is? acting_user or new_record?
end

Saves a db call if creator isn't already loaded.

The collection for select-many doesn't do any prefiltering so you will
probably want to modify the options to only grab the relevant ones
anyway. Still, I'd make sure the permissions were working right first
before doing that.

Mark Sobkowicz

unread,
Nov 17, 2010, 3:16:53 PM11/17/10
to hobo...@googlegroups.com
That solved my problem. Maybe the "or new_record" allowed the page to be built, and then the creator_is? allowed the popup to be filled. Someday I'll wade through the hobo gem and try to figure it out.

Thanks!

Mark

Peter Ehrlich

unread,
Nov 18, 2010, 2:11:17 AM11/18/10
to Hobo Users
Looking back - I believe what I said in my last post would have
returned nil for anything other than tag. That's not exactly
desired..

Mark Sobkowicz

unread,
Nov 18, 2010, 10:59:21 PM11/18/10
to Hobo Users
I am still working on the problem of users tagging recipes. I could not use <select-many>, because <select-many> requires that the items being selected from have unique names, and I want users to make their own tags, so that some might indeed have the same name. I want the users to tag recipes on the show-page, rather than the edit page, since only the owner of a recipe can edit the recipe. So on the recipe show page I put:

<form update="recipe">
<check-many:tags/>
<submit label="Update Tags"/>
</form>

And I get the right thing on the page - a list of the user's own tags, with checkboxes. If I click the "Update Tags" button, I get an error.

ActiveRecord::AssociationTypeMismatch (Tag expected, got String):
hobo (1.0.1) lib/active_record/association_proxy.rb:20:in `raise_on_type_mismatch'
hobo (1.0.1) lib/hobo/model.rb:399:in `send'
hobo (1.0.1) lib/hobo/model.rb:399:in `attributes='
hobo (1.0.1) lib/hobo/permissions.rb:194:in `user_update_attributes'
hobo (1.0.1) lib/hobo/permissions.rb:171:in `with_acting_user'
hobo (1.0.1) lib/hobo/permissions.rb:193:in `user_update_attributes'
hobo (1.0.1) lib/hobo/model_controller.rb:593:in `hobo_update'
hobo (1.0.1) lib/hobo/model_controller.rb:156:in `update'
hobo (1.0.1) lib/hobo/controller.rb:23:in `call'
hobo (1.0.1) lib/hobo/controller.rb:23:in `included_in_class'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'


By the way, the page itself freezes on the browser window (Safari), and the error page html shows up as text in a modal dialog box - I can't get rid of it and have to quit the browser.


kevinpfromnm

unread,
Nov 19, 2010, 4:06:15 PM11/19/10
to Hobo Users
You already had it working with select-many right? So it's got
the :accessible => true for the tags association.

that particular part of the trace doesn't help much since it's all
general code. I'd be interested in the parameters sent with the call,
any custom controller update (which it looks like that's not the
case), and the relevant parts of the models.

Mark Sobkowicz

unread,
Nov 20, 2010, 6:55:36 AM11/20/10
to hobo...@googlegroups.com
The controller for show has not been changed. The parameters sent are:

Processing RecipesController#update (for 127.0.0.1 at 2010-11-20 06:41:23) [PUT]
Parameters: {"page_path"=>"recipes/show", "authenticity_token"=>"", "id"=>"3-giant-pickle", "recipe"=>{"tags"=>["", "@3", "@4"]}, "_"=>""}


In the meanwhile I wrote one in erb, like this:

<% form_for @recipe do %>
<% for tag in Tag.find(:all) %>
<% if tag.owner_is? current_user then %>
<%= check_box_tag "recipe[tag_ids][]", tag.id, @recipe.tags.include?(tag) %>
<%= tag.title %>
<% end %>
<% end %>
<%= submit_tag 'Save' %>
<% end %>

It works, and its parameters sent are:

Processing RecipesController#update (for 127.0.0.1 at 2010-11-20 06:41:10) [PUT]
Parameters: {"commit"=>"Save", "authenticity_token"=>"", "id"=>"3-giant-pickle", "recipe"=>{"tag_ids"=>["1", "3", "4"]}}

Reply all
Reply to author
Forward
0 new messages