Ruby on rails model and controllers inside of different namespaces - ruby-on-rails

OK. This is insane.
I'm new to RoR and I really want to get into it as everything about it that I have seen so far makes it more appealing to the type of work that I do.
However, I can't seem to accomplish a very simple thing with RoR.
I want these controlers:
/admin/blog/entries (index/show/edit/delete)
/admin/blog/categories (index/show/edit/delete)
/admin/blog/comments (index/show/edit/delete)
... and so on
And these models:
Blog::Entry (table: blog_entries)
Blog::Category (table: blog_categories)
Blog::Comments (table: blog_comments)
... and so on
Now, I have already gone though quite a bit of misery to make this work. My first attempt was with generating scaffolding (I'm using 2.2.2). I generated my scaffolding, but had to move my model, then fix the references to the model in my controller (see Ruby on Rails model inside namespace can't be found in controller).
That is already a big of a pain, but hey, I got it to work. Now though form_for won't work and I cannot figure out how to use the url helpers (I have no idea what these are called... they are the automatically generated methods that return URLs to controllers associated with a model). I cannot figure out what their name is. My model is Blog::Entries. I have tried to mess with the route.rb's map's resource method, but no luck. When I attempt to use form_for with my model, I get this error
undefined method `blog_entries_path' for #<ActionView::Base:0xb6848080>
Now. This is really quite frustrating. I am not going to completely destroy my code's organization in order to use this framework, and if I cannot figure out how to accomplish this simple task (I have been researching this for at least 5 hours) then I simply cannot continue.
Are there any ideas on how to accomplish this?
Thanks
EDIT
Here are my routes:
admin_blog_entries GET /admin_blog_entries {:controller=>"admin_blog_entries", :action=>"index"}
formatted_admin_blog_entries GET /admin_blog_entries.:format {:controller=>"admin_blog_entries", :action=>"index"}
POST /admin_blog_entries {:controller=>"admin_blog_entries", :action=>"create"}
POST /admin_blog_entries.:format {:controller=>"admin_blog_entries", :action=>"create"}
new_admin_blog_entry GET /admin_blog_entries/new {:controller=>"admin_blog_entries", :action=>"new"}
formatted_new_admin_blog_entry GET /admin_blog_entries/new.:format {:controller=>"admin_blog_entries", :action=>"new"}
edit_admin_blog_entry GET /admin_blog_entries/:id/edit {:controller=>"admin_blog_entries", :action=>"edit"}
formatted_edit_admin_blog_entry GET /admin_blog_entries/:id/edit.:format {:controller=>"admin_blog_entries", :action=>"edit"}
admin_blog_entry GET /admin_blog_entries/:id {:controller=>"admin_blog_entries", :action=>"show"}
formatted_admin_blog_entry GET /admin_blog_entries/:id.:format {:controller=>"admin_blog_entries", :action=>"show"}
PUT /admin_blog_entries/:id {:controller=>"admin_blog_entries", :action=>"update"}
PUT /admin_blog_entries/:id.:format {:controller=>"admin_blog_entries", :action=>"update"}
DELETE /admin_blog_entries/:id {:controller=>"admin_blog_entries", :action=>"destroy"}
DELETE /admin_blog_entries/:id.:format {:controller=>"admin_blog_entries", :action=>"destroy"}
home / {:action=>"index", :controller=>"index"}
/:controller/:action/:id
/:controller/:action/:id.:format
That dosn't look right. Here is my routes.rb (comments removed):
ActionController::Routing::Routes.draw do |map|
map.resources :admin_blog_entries
map.home '', :controller => 'index'
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end

have you tried looking at the routes list that "rake routes" gives you? if your routes.rb is correct, it should show you the correct name for the blog entries route.
also, maybe this can help: http://www.coreywoodcox.com/2008/08/18/rails-namespaces-subdomains/.
edit:
well, then the correct way to call the route is admin_blog_entries_path instead of blog_entries_path.

Your routes.rb should look like this:
map.namespace :admin do |admin|
admin.namespace :blog do |blog|
blog.resources :entries
blog.resources :categories
...
end
end
but I'm not sure how to handle this '/blog/' part in your url (I didn't use any namespace in my models yet). But with these routes you will be able to use:
admin_blog_categories_path => '/admin/blog/categiries'
admin_blog_category_path(#some_category) => '/admin/blog/categories/1'
and so on.

OK, here my rather hacky way of doing it, which I don't like but does work.
In my case I have the models Blog::Article, Blog::Comment, they are nested in the routes. One caveat if using this approach is in the Blog::CommentsController when loading the article you can expect params[:article_id] or params[:blog_article_id]. By no means nice, but like I said. It does work :/
blog.resources :articles do |article|
article.resources :comments
end
blog.resources :blog_articles, :controller => 'articles' do |blog_article|
blog_article.resources :blog_comments, :controller => 'comments'
end

Related

Using URL helpers from the console in Ruby on Rails 2.3.11

I'm trying to use URL helpers in a 2.3.11 Ruby on Rails application, but I'm facing many problems with whatever the solution I try...
I've read a lot of "solutions" like including include ActionController::UrlWriter before trying to get a path, but I get the same error every time:
>> app.users_path
NameError: undefined method `new_suggestion_path' for class `ActionController::Integration::Session'
I can't find the problem with this. I have a "suggestions" controller and a "new" action on it... Is there any other way to fix this and get a URL from console and/or Rake?
You need to have resource routes defined for the named routes you are trying to access.
To make suggestion paths available in Rails 2.3, add a resource route config/routes.rb:
ActionController::Routing::Routes.draw do |map|
map.resources :suggestions
end
That will define the following routes:
suggestions GET /suggestions(.:format) {:controller=>"suggestions", :action=>"index"}
POST /suggestions(.:format) {:controller=>"suggestions", :action=>"create"}
new_suggestion GET /suggestions/new(.:format) {:controller=>"suggestions", :action=>"new"}
edit_suggestion GET /suggestions/:id/edit(.:format) {:controller=>"suggestions", :action=>"edit"}
suggestion GET /suggestions/:id(.:format) {:controller=>"suggestions", :action=>"show"}
PUT /suggestions/:id(.:format) {:controller=>"suggestions", :action=>"update"}
DELETE /suggestions/:id(.:format) {:controller=>"suggestions", :action=>"destroy"}
Now you can use those routes in the console:
>> app.new_suggestion_path
=> "/suggestions/new"
>>

Rails 3 routing and namespaces

I want to have a namespaced controller called 'portal'.
in this will be nested resources such as companies and products.
I'd like routes like :
/portal/:company_id/product/:id to work
I can get
/portal/company/:company_id/product/:id to work but would like to eliminate the 'company' in the url
Hope that is clear. Please keep in mind that I need the namespaced module portal to exist.
I think you could use scope to achieve what you want. Perhaps like this:
namespace "portal" do
scope ":company_id" do
resources :products
end
end
That will generate the following routes:
portal_products GET /portal/:company_id/products(.:format) {:action=>"index", :controller=>"portal/products"}
POST /portal/:company_id/products(.:format) {:action=>"create", :controller=>"portal/products"}
new_portal_product GET /portal/:company_id/products/new(.:format) {:action=>"new", :controller=>"portal/products"}
edit_portal_product GET /portal/:company_id/products/:id/edit(.:format) {:action=>"edit", :controller=>"portal/products"}
portal_product GET /portal/:company_id/products/:id(.:format) {:action=>"show", :controller=>"portal/products"}
PUT /portal/:company_id/products/:id(.:format) {:action=>"update", :controller=>"portal/products"}
DELETE /portal/:company_id/products/:id(.:format) {:action=>"destroy", :controller=>"portal/products"}
Edit: Accidentally used resource instead of resources. Fixed now.
You can customize the routes to nearly whatever you want if you spell them out directly, like this:
match '/portal/:company_id/product/:id', :to => 'companies_products#show'
The :to part specifies the controller and action to use, something that should match what you have in your routes now. If you're not sure what that is, rake routes will tell you its specific interpretation.

scope equivalent in rails 2.3.x?

Is there a way to generate a group of routes under an admin scope without having to create a new physical directory (like namespace requires you to).
I know that in Rails 3 there is a scope method on the route mapper, and this appears to do what I want, but apparently it doesn't exist in Rails 2.3.x
My goal is to have a route like this: "/admin/products" map to "app/controllers/products_controller, not "app/controllers/admin/products_controller".
Is there any way to accomplish this in Rails 2.3.x?
Sure, you need to use :name_prefix and :path_prefix to get to what you want:
ActionController::Routing::Routes.draw do |map|
map.with_options :name_prefix => 'admin_', :path_prefix => 'admin' do |admin|
admin.resources :products
end
end
Will yield routes:
admin_products GET /admin/products(.:format) {:controller=>"products", :action=>"index"}
POST /admin/products(.:format) {:controller=>"products", :action=>"create"}
new_admin_product GET /admin/products/new(.:format) {:controller=>"products", :action=>"new"}
edit_admin_product GET /admin/products/:id/edit(.:format) {:controller=>"products", :action=>"edit"}
admin_product GET /admin/products/:id(.:format) {:controller=>"products", :action=>"show"}
PUT /admin/products/:id(.:format) {:controller=>"products", :action=>"update"}
DELETE /admin/products/:id(.:format) {:controller=>"products", :action=>"destroy"}
It appears to be not well documented, but namespace is actually a very simple wrapper for with_options. It sets the :path_prefix, :name_prefix, and :namespace options, of which I believe you only want the first, so:
map.with_options :path_prefix => 'admin/' do |admin|
admin.connect ':controller/:action'
end
I'm going through this from reading the code. It looks like :name_prefix is used to give named routes a prefix, and :namespace is used to actually look in subdirectories.

Rails 2 Namespace and Shallow Routes Issue

I've written the admin area of a particular rails app and now I'm ready to set it as own section within the website.
Therefore, it will be /admin
However, I didn't want to have it as /admin within the route itself I wanted to have something less common, so I added a couple of hyphens before and after it.
So the route is /-admin-/ and the namespace is Admin.
After setting this up using :path_prefix => "/-admin-", I have the following code block:
map.namespace "/-admin-/", :name_prefix => "", :path_prefix => "/-admin-" do |admin|
This works for all but shallow routes, instead, in the rake routes output the output is:
new_page GET /-admin-/areas/:area_id/pages/new(.:format) {:action=>"new", :controller=>"admin/pages"}
edit_admin_page GET /admin/pages/:id/edit(.:format) {:action=>"edit", :controller=>"admin/pages"}
admin_page GET /admin/pages/:id(.:format) {:action=>"show", :controller=>"admin/pages"}
PUT /admin/pages/:id(.:format) {:action=>"update", :controller=>"admin/pages"}
DELETE /admin/pages/:id(.:format) {:action=>"destroy", :controller=>"admin/pages"}
areas GET /-admin-/areas(.:format) {:action=>"index", :controller=>"admin/areas"}
POST /-admin-/areas(.:format) {:action=>"create", :controller=>"admin/areas"}
new_area GET /-admin-/areas/new(.:format) {:action=>"new", :controller=>"admin/areas"}
Notice how the shallow-routed routes are prefixed as /admin/ and not as /-admin-/ (as are their parent routes).
Any ideas on how to get around this? Is this a bug in rails or do I need to work around it? I tried adding the :path_prefix to each nested route but it doesn't do anything?
Any ideas?
I'm not sure about your rationale on not using /admin - security through obscurity isn't really security - you should be using something like authlogic to keep out unauthorised users.
Try the following to namespace your admin controllers:
map.namespace :admin, :path_prefix => "-admin-" do |admin|
admin.resources :users
admin.resources :pages
end
A sample generated route:
admin_users GET /-admin-/users(.:format) {:controller=>"admin/users", :action=>"index"}
There is no way to get around this. Turns out that all versions of Rails will break down the URL and its resource names to their lowest points when they're set to shallow. The only solution to this is to set all of your resource routes manually without using map.resources.

rails foobar_path(3) returnes strange path: "/foobar.3/" instead of "/foobar/3/

Hi i have this starnge behavoir...
<%= link_to image_tag("image.png"), brain_path(1), :method => "put" %>
produces:
<img alt="Research_4" src="/images/image.png" />
a href="/foobar.1" this is the strange part :( any ideas whqt is causing this?
rake routes gives the following:
new_brain GET /brain/new(.:format) {:controller=>"brains", :action=>"new"}
edit_brain GET /brain/edit(.:format) {:controller=>"brains", :action=>"edit"}
brain GET /brain(.:format) {:controller=>"brains", :action=>"show"}
PUT /brain(.:format) {:controller=>"brains", :action=>"update"}
DELETE /brain(.:format) {:controller=>"brains", :action=>"destroy"}
POST /brain(.:format) {:controller=>"brains", :action=>"create"}
How do you route your foobar? (singular or plural? resource or resources?)
Are you sure that you're using foobar_path(1), not foobars_path(1) (singular form)
in real life foobars_path(1) will return /foobars.1 and foobar_path(1) - /foobar/1
as I see you have to use brain_path(1) not brain_path(1)
UPD
Change your route.rb
map.resources :brain
it will be better if you'll rename your controller into pluralize brains - it is more conventional when you are using resources

Resources