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.
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!
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?
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.