Rails doesn't automatically load a template when in a namespace - ruby-on-rails

Take routing like the following:
namespace :auth do
get 'login', to: 'auth#login'
end
With a simple empty method in the controller:
def login
end
Without the namespace, it picks up the login template automatically with no problem. When I move it to the namespace, however, it switches to a 204 No Content response and shows a rails warning page. I can add render to my controller method, but it should be automatic. Where am I going wrong?

The path to the views must be something like:
app/views/namespace/controller/view.html.erb
So, in your case both namespace and controller have the same name, so the path to the views should be:
app/views/auth/auth/login.html
Instead of:
app/views/auth/login.html

Related

Setting default page for Controller in Rails

In rails how to set the default page for controller. In my application I have a controller named "greet" which have two actions "welcome"
and "wishes". So while calling the welcome page like "localhost:3000/greet/welcome" is properly worked.
But My requirement is if I didn't
give the action name for that controller like "localhost:3000/greet", then it takes the default page associated for that controller only. How to do this
in rails 4.2. I tried to make an index action within greet controller. But it didn't work. Can anyone help me to solve this problem ?
in your routes.rb add line:
get '/greet' => 'greet#welcome'
you must also in folder view create folder greet and in this folder you have to create file welcome.html.erb
Rails work with REST concept. So, according to this when you just call localhost:3000/greet it will search greet#index method. Well, If you want to see any custom method while usinglocalhost:3000/greet, you will need to write in file config/routes.rb like:
Rails.application.routes.draw do
get 'greet', :to => 'greet#welcome', :as => :greet
end
Hope this will help.
Try this.
get '/greet', to: 'greet#welcome'
Rails.application.routes.draw do
resource :greet, controller: 'greet' do
get 'welcome'
get 'wishes'
#Default resource routing
get '/', to: 'greet#welcome'
end
end

Understanding routing with rails

I am trying to make a stupid simple CMS for one of my clients using rails. I generated scaffolding for Page and have been successful at creating and rendering those pages, however, the routing is ugly.
Right now, if I want to view the home page, I get a url like this: example.com/pages/1
I'd like to accomplish 2 things:
How do I set the routing so that example.com automagically grabs the page named "home"
and
How do I set the routing so that example.com/page/page_name performs a
#page = Page.find_by name: 'page_name'
Q1:
How do I set the routing so that example.com automagically grabs the page named "home"
In `routes.rb:
root :to => '[controller]#[action]'
#'pages#home' for example, if your home page is in `pages_controller`
# and uses the `home` action
Q2:
How do I set the routing so that example.com/page/page_name performs a
#page = Page.find_by name: 'page_name'
match '/page/:name', :to => 'pages#some_name', :as => :some_name
this would generate the following in $rake routes:
some_name /page/:name(.:format) pages#some_name
when you link to (or redirect, or otherwise access) this page, you'd write
link_to "click this link!", some_name_path(#SomeModel.some_name)
To accomplish the first thing you need to open the file routes.rb which is in the config folder and add the following:
root to: "home#index"
I'm assuming you have a controller named home which contains a method called index and this is the one that displays the home page.
If you want to make it the same as example.com/pages then you would have to use
root to: "pages#index"
to make a general rule you need to use
root to: "controller#method"
Don't forget to remove the index.html from the public folder too.
I recommend you make the blog application presented here:
http://guides.rubyonrails.org/getting_started.html
It can help you understand more.
Here's a solution that assumes your controller is named pages_controller instead of page_controller.
Add these routes in config/routes.rb:
root to: 'pages#show', page_name: 'home'
get 'pages/:page_name', to: 'pages#show'
For the controller app/controllers/pages_controller.rb:
class PagesController < ApplicationController
def show
#page = Page.find_by(name: params[:page_name])
end
end
Note: In rails4 the find_by dynamic finders have been deprecated... so if you're app is on 4 you should look into updating them. These docs have further details.
Also, if you're just trying to get static looking urls then I would definitely go with Marian Theisen's suggestion and use friendly_id.

Rails view template path loading seems incorrect

I have a problem where Rails is searching an additional subdirectory based on the controller path. Is there a way to get rails to stop searching one extra subdirectory? I kind of like the directory structure that I have now. Here's the details:
Rails will return this error message. As you can see, it's going for v1 twice:
Template is missing
Missing template api/v1/v1/print
I have a controller in app/controllers/api/v1/v1_controller.rb and a view in app/views/api/v1/print.html.erb
The specific route in config/routes.rb is (semi-truncated):
namespace :api do
scope module: :v1 do
match "v1/print",
:to => "v1#print"
end
end
Based on the routes, it looks OK. Rake routes show this:
api_v1_print GET|POST /api/v1/print(.:format) api/v1/v1#print {:format=>"html"}
Why is it going one directory too deep?
The problem is that Rails assumes there's a subdirectory per each controller. The duplication is formed since you have v1 in the module and in the controller name. I wouldn't go against Rails' conventions. Instead I would change the name of the controller to API controller (or something similar) and put the templates under the directory called API.
In case you still want to do this, simply use render within your print action and specify the exact file you'd like to use (see here)
just remove the v1 from the match, like this:
namespace :api do
scope module: :v1 do
match "print",
:to => "v1#print"
end
end
EDIT
sorry, the problem is in your template folder.
app/views/api/v1/print.html.erb
app/views/(namespace)/(module)/(action) <- you have forgoten the controller
the right one would be:
app/views/api/v1/v1/print.html.erb

How to create view in RoR if skipped during controller generation

When I run this:
rails generate controller hello index
it no doubt generates hello controller, but accidentally when I run another command like this:
rails generate controller world
it creates the world controller successfully, but missed the Route "world/index" like as "hello/index". For this mistake I need to use destroy controller and then generate it once more, is thr some kind of mid way command that I can generate if forgotten something rather than destroying and creating every time.
This command
rails generate controller contact-us index
creates a route as contact_us/index or contact_us after changing routes.rb under config folder. How could I create a more SEO friendly URL in RoR? Like localhost:3000/contact-us?
I am working on some very basic rules to follow RoR..like 3 static pages (Home, About us, Contact Us) Just simple html content to understand more, will certainly add more features to it as well.
localhost:3000/home
localhost:3000/About_us
localhost:3000/contact_us
I created this via creating home, About_us, contact_us controller command and then changed html in views. Since I am on an initial phase, I read somewhere for static pages we can create this in our public like what we have error pages there in the folder or the approach im using is correct?
when you use rails generator it will create controller and view folder for it
rails generate controller test
will create test_controller.rb and view/test folder
rails generate controller test index
will create test_controller.rb and view/test/index.html.erb file as well as define a route for you
However what its sounds like you are trying to do is have single controller with static pages what i would suggest you do is generate home_controller with home, aboutus, and contact actions and than map the routes to them like so
rails generate controller home
controllers/home.rb
HomeController < ApplicationController
def index
end
def about_us
end
def contact
end
end
routes.rb
match '/home', :to => 'home#index'
match '/About_us', :to => 'home#about_us'
match '/Contact_us' , :to=> 'home#contact_us'
and than define your views in
views/home/index.html.erb
views/home/about_us.html.erb
views/home/contact_us.html.erb

Rails beginner config/routes.rb issue

I am having a little trouble understanding what config/routes actually routes to. For example lets say I started a brand new project and generated a Users controller and edited my config/routes.rb to look like this:
config/routes.rb
SampleApp::Application.routes.draw do
match '/signup', to: 'users#new'
end
I start the server and as expected, it says I don't have a "new" action in my Users controller. I create one:
users_controller.rb
class UsersController < ApplicationController
def new
end
I refresh the page and as expected it tells me I need a users/new template. So my question is: do my view templates always have to be the same as the controller and action names in "(controller name)/(action name)" format (in this case users/new.html.erb)? Is it not possible to name my template something random (e.g. users/rubyonrailsmeetup.html.erb instead of users/new.html.erb) if have a controller action linked to one of the site's functions?
Also, does adding "resources :users" to config/routes.rb by default match the view template file names with the behavior I mentioned above so that views must be named after their "controller/action" names?
Sorry for the bother, I'm just trying to figure out what's part of Rails' magic and what isn't.
Rails attempts to render the template with the same name as the action by default, if no other render or redirect is invoked in the controller action. Basically, there's an implicit render :action at the end of every controller action.
But you can override this easily enough by adding an explicit render, e.g.,
render :rubyonrailsmeetup
Edit for clarity: this call to render goes in the controller code, not in config/routes
do my view templates always have to be the same as the controller and action names in "(controller name)/(action name)" format
These are defaults, you can render any view from the action by giving render :view_file_rel_path at the end of the action
does adding "resources :users" to config/routes.rb by default match the view template file names
Anything added in routes.rb is directly related upto controllers only, i.e. it matches the request and maps it to the controller/action. Logic of view comes only inside the action code

Resources