Hello, I'm not sure wether this has already been asked on this forum. I'm trying to create a method in my model which returns a path/url. It seems like I can't have acces to the restfull routing system from my models. Here is my model: class Componentgroup < ActiveRecord::Base acts_as_tree :order => "name" def getPage self.root.pageresource.page end def getLinkToParent if self.root == self pageresources_path getPage else groupresources_path self.parent end end end getLinkToParent returns this ugly error: undefined method `pageresources_path' for #<Componentgroup:0x48b6664> Any ideas for a workaround are welcome.
on 2007-04-17 17:08
on 2007-04-17 17:54
You are not allowed to access controller-related stuff in the models. It violates MVC. You will find that you can't access sessions, request parameters, or other things back there. You may want to use your models without using your controllers, like for backend stuff. You might need a whole new controller layer at some point, instead of the HTML-based one (like flex maybe, so restful routing isn't an issue. I recommend making a helper that takes the model as a parameter. If there's a specific reason you need to have that information in there, you can hack around it by including the appropriate modules in your model class. A purist would find this ugly... if you're hitting a wall with MVC, it might be because you're trying to do something you shouldn't. (That's not always true.. there are valid reasons for violating MVC, but they are rare.) Maybe you could explain in more detail the feature you're trying to implement, and someone could come up with an alternative solution for you. Good luck!
on 2007-04-17 20:00
Thanks for the information. I guess you're right that I'm violating MVC principles so there must be a better solution. I was already thinking about a helper module but I seems to be a bit of overkill for this tiny little method. Anyway, I'm building a little component based content management system. Each site consists of pages, a page consists of single components and/or componentgroups. Each componentgroup consists of single components or other componentgroups. So componentgroups can be nested deeply. That's why I defined "acts_as_tree" in the componentgroup model. The structure of a website would look like this: -> site -> page -> component -> component -> componentgroup 1 -> component -> componentgroup 2 -> component -> component -> other page ... def getLinkToParent if self.root == self pageresources_path getPage else groupresources_path self.parent end end The "getLinkToParent" method generates the proper URL to a lower level. So if a user is viewing "componentgroup 2" child resources/components, he needs a "back" link to the resources of "componentgroup 1". In this case the parent of componentgroup 2 is also a componentgroup. The method will therefore redirect the user to "groupresources_path self.parent". BUT if the user is at the level of "componentgroup 1" (= root of tree), he needs to be redirected to page level for viewing all child resources of a page. So I wanted an elegant solution for creating a back link when viewing the list of components contained in a componentgroup. Something like this: <%= link_to 'Back', @componentgroup.getLinkToParent %> I hope this makes any sense :). It's not easy to make a an abstraction of the whole thing :) Maby this is also a good time to discuss my concept?
on 2007-04-19 15:55
No, you're on the right track.... helper method should work fine. In your view, you'd do this: <%=link_to "back", parent_link_url(@componentgroup) %> # determines the parent link. def parent_link_url(component) component.root == component ? pageresources_path component : groupresources_path self.parent end Let me know if that's gonna work for you.