Creating a nested custom resource in rails 3 - ruby-on-rails

I have an professional model and a citizen model. What i am trying to do is a nested citizen registration inside the professional model, but i am stumbling a lot...
i was using in my routes:
get "professional/citizen_edit/:id" => "professional#citizen_edit", as: :professional_citizen_edit
get "professional/cidadao_show/:id" => "professional#citizen_show", as: :professional_citizen_show
put "profissionais/cidadao_update/:id" => "professional#citizen_update", as: :professional_citizen_update
And using custom controller actions everywere
And was almost done, but i had got stuck when trying to add a button for a new citizen
(my form page was stuck in the update action and i cant get it to work with both actions)
While trying to solve this issue, i found this http://guides.rubyonrails.org/routing.html
and this:
namespace :professionals do
resources :registrations
end
Looked a more elegant way to deal with my problem. But now i dont know what to do with the controller! I got these routes:
professionals_registrations GET /professionals/registrations(.:format) professionals/registrations#index
POST /professionals/registrations(.:format) professionals/registrations#create
new_professionals_cadastro GET /professionals/registrations/new(.:format) professionals/registrations#new
edit_professionals_cadastro GET /professionals/registrations/:id/edit(.:format) professionals/registrations#edit
professionals_cadastro GET /professionals/registrations/:id(.:format) professionals/registrations#show
PUT /professionals/registrations/:id(.:format) professionals/registrations#update
DELETE /professionals/registrations/:id(.:format) professionals/registrations#destroy
And i tried to add a custom controler "registrations" either inside app/controllers or app/controllers/professionals but i cant find the controler right path and keep getting
at: http://127.0.0.1:3000/Profissionais/registrations)
uninitialized constant Profissionais::RegistrationsController
Anyone have any clue of what to do now?

When using namespaces you have to do two things:
Move all controllers to a folder under app/controllers/ with the same name as your namespace
Let your controllers inherit from a controller with the same name of your namespace (in your case Profissionais)
The reason why you are getting that error is that the parent controller Profissionais does not exist (i.e. uninitialized constant)
As the documentation states, all your controllers must be under a namespace (in your case Profissionais::) as you defined it in routes.rb.
HINT:
I haven't tried it myself but it may also be possible to use modules to create your namespace instead of inheriting from a parent controller residing in app/controllers/. For more see here

Related

Rails routing issue, can't figure out the link path

Let me fair from the outset, and tell you that I've 'solved' the problem I'm describing. But a solution that you don't understand is not really a solution, now is it?
I have a resource, Newsbites. I have an index page for Newsbites. All my CRUD actions work fine.
I created a separate index (frontindex.html.erb) that acts as the front page of my website to show the newest Newsbites. The formatting is different from my normal index so readers get a larger photo, more of the text of the article(more ads too:).
In my routing table, I have the following statements:
resources :newsbites
get 'newsbites/frontindex'
root 'newsbites#frontindex'
Rake routes show the following:
newsbites_frontindex GET /newsbites/frontindex(.:format) newsbites#frontindex
If I load my website from the root (localhost:3000), it works great. There is a separate menu page that is rendered at the top, and it loads fine. I can click on all links, except the 'Home' link, and they work fine.
The 'Home' link is:
<%= link_to 'Home', newsbites_frontindex_path %>
When I click on the linked, I get the following error:
Couldn't find Newsbite with 'id'=frontindex
The error points to the 'show' action of my Newbites controller. Here are the frontindex and show def from the controller. They appear exactly as I'm posting them:
def frontindex
#newsbites = Newsbite.all
end
def show
#newsbite = Newsbite.find(params[:id])
end
I don't get it. Why is the show action being called by newbites_frontindex_path when there is both a def and views that match? Now, I can get around this by simply pointing home to root_path. But that doesn't help me understand. What if this was not the root of the site?
Any help would be greatly appreciated.
Actually I'm very surprised your code worked at all. A route must define two things
Some sort of regex against which the URL of the user is matched (newsbites/frontindex is different than newsbites/backindex)
What do you want to do for a given URL ? You want to point to a controller action
Rails won't usually "guess" what that action is. Or maybe, he was still able to "guess" that you wanted to use the newsbites controller, but it didn't guess the action right this time :(.
You should declare the root like this, which is what you did
root 'controller#action'
For the rest, there are two ways you can declare it. I prefer the second one
resources :newsbites
get 'newsbites/frontindex', to: 'newsbites#frontindex'
resources :newsbites do
# stuff added here will have the context of the `newsbites` controller already
get 'frontindex', on: :collection # the name of the action is inferred to be `frontindex`
end
The on: :collection, means that 'frontindex' is an action that concerns ALL the newsbites, so the URL generated will be newsbites/frontindex.
On the other hand get 'custom_action', on: :member, means that the custom_action targets a specific item, the URL generated would look like newsbites/:id/custom_action
EDIT : Rails also generate path_helpers based on the route declaration
get 'test', to: 'newsbites#frontindex'
get 'test/something', to: 'newsbites#frontindex'
resources :newsbites do
get 'frontindex', on: :collection
get 'custom_action', on: :member
Will generate path helpers
test_path
test_something_path
# CRUD helpers : new/edit/show/delete, etc. helpers
frontindex_newsbites_path
custom_actions_newsbite_path(ID) # without s !
You can always override this by adding an as: option
get 'custom_action', on: :member, as: 'something_cool'
# => something_cool_newsbites_path
Rails routes thinks that frontindex is an id. That's what the error message says. So it goes to GET newsbite/:id which maps to show.
You need to find a way let Rails routes know that frontindex is not an id.
On a side note: The order in which you define routes matters. The first one matched will be used. If you have GET newsbite/:id and GET newsbite/frontindex then the one that appears first will be matched. In your case this is the first one.
Maybe try to change the order.

How to add a view in rails

I am quite new to rails but i have searched a lot how to do this but it doesnt seem to work for me. Im trying to create a new view called request for my model called steppy_steps, so i created a new file in the views directory called request.html.rb, added this to my routes, match '/request' => 'pages#request', also tried get "steppy_tests/home", and lastly added (def request, end), to my Steppy_Tests_Controller.rb but when i check the url it gives me an error:Couldn't find SteppyTest with id=home
I cant figure out what to do any help would be great! Thanks in advance.
You should read up on the MVC programming pattern (which is what Rails is based on)
In order to make a view, you need to have the controller and model aspects in place too. I think you're doing this already, but to help you understand more, I'll outline below:
Views : Controller Actions
If you want to show a view from the steppy_steps controller, you need to first have a controller action set up to handle the request. You'd normally use a self-named controller for this (controller name steppy_steps), and have various actions for that
In your routes, you'll then "capture" the request to your steppy_steps controller like this:
#config/routes.rb
resources :steppy_steps
This will create a set of RESTful routes, which you can then translate into your controller, like this:
#app/controllers/steppy_steps_controller.rb
def index
#Index code
end
def show
#Show code
end
This will allow you to create a views directory which can contain the views for /views/steppy_steps/show.html.erb and /views/steppy_steps/index.html.erb
Routes Are Super Important
The error you're getting is caused by you sending /home to your view
The problem here is that if you're using a route which has an in-built id param (the show action routes have this), then Rails will look for the extra params after the URL
To fix this, you'll have to provide more of your code, but I also believe you'd be better understanding the fundamentals of Rails a little more
Adding Routes
You can add routes & views as you wish
If you're looking to add a requests route / view, I'd do this:
#config/routes.rb
resources :steppy_steps do
collection do
get :requests
end
end
This will allow you to create /steppy_steps/requests

How to add new controllers to devise controllers structure?

i have a functional application that have a devise merchant model and i've overwritted the registration controller, so i have a folders structure like
app/controllers/merchants/registrations_controller.rb
now i'm trying to add a new controller called products in order to have something like
app/controllers/merchants/registrations_controller.rb
app/controllers/merchants/products_controller.rb
When i perform
rails g controller
i get all the files required, but for some reason next to it i can't perform rake's or generators 'cause of this error
undefined method `devise' for #<Class:0x007f929f5b5408>
this ever happen when i add a new controller to a devise folder, in this case the merchants folder... is there a reason why i can not or i should not do this?
how can i accomplish this?
maybe there is a better approach to do this... if is that the case, could be great know it ;)
update: the goal is group all the controllers related to the merchants under merchants folder, also i figured out that the issue is generated by a helper file generated in app/helpers/merchants/products_helper.rb so deleting this file the exception dissapears... but why?
Why did you add the products_controller to your devise merchants folder? If the goal is to authenticate merchants for the products controller, here is the way to do it:
Put your product_controller.rb in app/controller/ as usual and had this filter in it:
before_filter authenticate_merchant!
Check that you have this in your route.rb (for the custom registrations controller):
devise_for :merchants, :controllers => {:registrations => "merchants/registrations"}

adding a method to an existing controller

I'm pretty new to rails, and I'm hoping you can help me understand how the following works.
At present I have a controller named projects (projects_controller.rb). From what I understand of ROR each controller has some basic (inherent) methods such as index, new, create, edit, show, etc. I would like to add a method called "help" and a view to display the help information.
At present a user can create many projects. The projects contain a set of fields that are populated by the user. I would like to add a help page that the user can access (via a link on the project screen) which explains each project field and how to best fill it out. I would like this to be an independent page (not just info displayed on the project's page).
As of now, the URL to the projects is (when editing a project): localhost:3001/projects/id/edit
I would like for the path to the help file to be localhost:3001/projects/id/help
If I want the help file to be located in the path listed above, am I correct in assuming that I need to create a new method, called "help", in the projects controller? And if so, is there something that I need to add to routes.rb to make it function? And would I use a link_to function in the Haml to create a link to it?
I'm sorry if this seems confusing or a lot of question. I appreciate your time. If you have any suggestions on whether on the right path please let me know. Thank you so much!
I think currently you have this in routes
resources :products do
end
just replace this with
resources :products do
get :help, :on => :member, :as => :help
end
And add method in controller and add view named help.erb.html(if you r using erb) in views/product folder.
you can use help_path and help_url

Rails 3 don't find index page

I'm having a little trouble here with Rails 3.
I've created a controller called Admin. I've also defined a method called index and a view in app/views/admin/index.html.erb.
The problem is that when i go to http://localhost/myapp/admin i get a "Route not Found Error", but when I go to http://localhost/myapp/admin/index i get to the page I want.
I'm posting some links to the code, so you can check if there is any error, ok?
http://pastebin.com/UctUq44G
Thanks!
The issue is your routes.
There is no route for 'admin/'. This will add additional routes needed.
resources :admin
If your intention is to simply have semi static pages you can add
get 'admin'
Also some handy information :
http://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default

Resources