Rails view template path loading seems incorrect - ruby-on-rails

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

Related

Removing controller name from Rails URL route

This is my first Rails project, I am trying to piece things together slowly.
When I'm trying to view the page I generated using rails g controller <controller> <page>, I find myself going to 0.0.0.0:3000/controller/page.html, How can I configure it so that my route file globally allows viewing the page via the page name, rather than controller/page, if no such way exists, then how can I route controller/page.html to /page.html
I've looked around, and haven't really found any explanation, maybe I'm looking in the wrong places?
In config/routes.rb:
get '/page' => 'controller#action'
If your controller is:
class UsersController < ApplicationController
def something
end
end
Then config/routes.rb would be:
get '/page' => 'users#something'
For static pages you could want to use public folder though, everything you put there is directly accessible, for example public/qqqqqq.html would be accessed in localhost:3000/qqqqqq.html
We've just achieved this by using the path argument in resources method:
#config/routes.rb
resources :controller, path: ""
For you specifically, you'll want to make something like this:
#config/routes.rb
resources :static_pages, path: "", only: [:index]
get :page
get :other_page
end
#app/controllers/your_controller.rb
def page
end
def other_page
end
This will give you routes without the controller name. You'll have to define this at the end of your routes (so other paths come first)
Obviously this will form part of a wider routes file, so if it doesn't work straight up, we can refactor!
It sounds like this is a static page, so you can do as juanpastas says, or another option is to create a folder under your app/views directory to hold these pages. Maybe something like
app/views/static_pages/the_page.html.erb
Then in your config/routes.rb you can add:
match '/your_page_name', to: 'static_pages#the_page', via: :get

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.

Correctly mapping rails url

I have a controller in a subdirectory called fridges (the higher-level directory it is in is called categories). I have made an index page for the fridges controller and it works correctly when I navigate to "categories/fridges/index". However, it doesn't work when browsing to 'categories/fridges' as I want it to.
Here is how it is being routed in the route config:
map.namespace :categories do |categories|
categories.resources :fridges
end
What should I be doing to make the index page appear when navigating to the url 'categories/fridges' ?
In Rails 3, you can do:
namespace 'category' do
match '/fridges' => 'fridges#index'
resources :fridges
end
A similar approach can be taken for Rails 2.x. What you are looking for is the match '/fridges' => 'fridges#index', which should be defined in your namespace.
Hope that helps!

How to remove controller name in REST design in Rails3?

Given a User resource, it goes like this
/user/:shortname
But how can the controller name be removed to get just
/:shortname
How can I declare this in routes.rb while keeping all CRUD functionality instant?
Updated: After reading this I'm moving to Sinatra over Rails to handle this API-like design better.
Define a custom match:
match ':shortname' => 'users#action'
Replace action in users#action with the name of the action that is supposed to receive the request. Just remember to place it in the appropriate order in your routes file. Rails looks at each line of your routes file starting at the top and selects the first matching route. ':shortname' would match any first-level path, including /users! So put it below any routes using a first-level path, which would include all of your resource routes. Here's an example:
resources :users
resources :posts
match '/blog' => 'posts#index'
match ':shortname' => 'users#action'
In routes, you should be able to do something like
resource :users, :path => '/:shortname'
Try that out and rake routes to see if that comes out as expected.

Weird Routing Error in Rails When Manually Adding View

I am not sure what I am doing wrong but when I manually add the view "blah.html.erb" to my project and then visit myproject/dog/blah. It says the following:
Routing Error
No route matches "/dog/blah"
There is an action defined in DogController called "blah" which is the following:
def blah
end
NOTE: I add the view using TextMate. I add a new blank file. I think there is some wrong encoding attached to the .html.erb file.
For clarity, you need to either have each action listed explicitly in your routes.rb file; or you need a wildcard pattern to match the controller and action.
What's in your routes.rb file?
Better yet, you need to have something like this
match "/dog/blah", :to => "dog#blah", :as => :dog_blah
This tells your rails app that the url /dog/blah maps to the blah action in your DogController, and the :as option will give you a named route that you can use in your view in this case dog_blah_path.

Resources