How to setup routes for multidimensional requests? - ruby-on-rails

I wasnt sure what to call the title, but I guessed. :P
Basically I wanted to setup a somewhat complicated website, and I dont know how to setup the routes. Here is how it would work.
/ruby would show info on Ruby programming language
/ruby/rails would show info on ROR
/ruby/sinatra would show info on sinatra
/php would show info on PHP
/php/laravel would show info on Laravel
ETC.
Im not sure exactly how everything would work. I want a controller for each framework/language. I am thinking to making a folder for each language and having controller in it, but im not really sure if thats the best option.
EDIT: I forgot to mention that each langugae will have its own set of pages. EX.
/ruby/rails/models shows info on rails models
/ruby/rails/controllers shows info on rails controllers
/ruby/rails/routing shows info on rails routing
/ruby/oop talks about oop
/ruby/variables shows how to define variables
ETC. Its essentially going to be sort of like documentation.
Thanks!

Try http://guides.rubyonrails.org/routing.html Section 3.2, "Dynamic Segments"
get ':controller/:action'
Now create a controller for each language. For example, php.rb, ruby.rb, etc. Each framework is an action in that controller
class Ruby < ApplicationController
def rails
end
def sinatra
end
end
EDIT
I don't have the time to test this one at the moment, but let me know if it works or not :-)
# Routes.rb:
get ':controller/:action/:pagename'
And then for the Ruby class
class Ruby < ApplicationController
def rails
if template_exists?("#{params[:pagename]}", _prefixes)
render params[:pagename]
end
end
end

Related

Rails Tutorial- cannot get rails to recognize route

I am new to programming in general, someone referred me to railstutorial.org.
Specs: I am working on a cloud9 IDE, as suggested in the tutorial.
Information: I am on 1.3 of the rails tutorial, which is setting the root route.
The problem was initially my route did not effect the server launch (root page was still ruby default, not to 'application#hello'). Here are the files that the tutorial said to edit.
routes.rb
Rails.application.routes.draw do
root to: 'application#hello'
end
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def hello
render text: "Hello, world!"
end
end
There are a lot of comments that were defaulted into the files that I left out.
I have followed the instructions precisely. After I first had trouble, I thought I may have made an installation error, so I deleted my IDE and restarted, paying extreme attention to detail, especially versions.
I have tried $ rake routes, and my understanding it gives the message:
You don't have any routes defined!
That leads me to believe that the problem is the routes.rb file. I have tried changing the syntax to:
root to: 'application#hello'
I don't know a whole lot, such as how it would work using application, so I also tried:
root 'ApplicationController#hello'
and
root to: 'ApplicationController#hello'
These all result in the no routes defined message. I have no idea what is going on.
Thanks for any input or help!
You could try root 'application#hello' in your routes. Also, when starting out simple things like forgetting to save the file before trying things out on the browser can slip by; restarting the server takes care of a surprising number of foibles.
The rails documentation can also provide you a bit more information beyond the tutorial.
You probably want to move that action outside of the ApplicationController to another controller, but if you really insist, you can put this into your routes.rb:
get '/hello', to: 'application#hello', as: :hello
If you want the page to be the root, I would recommend creating a StaticPagesController and defining hello there, instead of putting it inside ApplicationController.
Here's what you can do:
Run rails g controller static_pages
Inside your StaticPagesController.rb, copy and paste your hello method that was inside ApplicationController.
Change the routes.rb to root 'static_pages#hello.
and you should have your desired result.
I've followed the same tutorial and I can say that the materials covered in the first two chapters are quite complicated at first if you are new to programming. It's only after you've done the entire tutorial that it will become clear to you how this routing thing (or any other details in these chapters for that matter) actually works.
However, since this idea of routing is very important, it's not a bad idea to understand how it works even if you are at an early stage in the tutorial.
The way you can create a route in rails is that you first specify a proper HTTP verb (GET, POST, PATCH, DELETE) with an appropriate path, the name of a controller, followed by a hash sign (#) and the name of an action defined in the controller.
Here controller is just a ruby class and an action a ruby method. (Since the basic principle of ruby on rails is "convention over configuration", it's important to get used to the terminology like controller, action, routing etc...)
When you say
get '/hello' => "application#hello"
(yes, you can use => in place of to:) as takeriho suggests, what happens is that a GET request to a URL of the type /hello(/ being "root path" as in www.example.com/(note the / at the end)) will get routed to the action, or method, named hello defined in a controller, or a class, named ApplicationController.
If you take a look at application_controller.rb, you can see that a method hello is defined within a class ApplicationController.
class ApplicationController < ActionController::Base
.....
def hello
render text: "Hello, world!"
end
end
Now if you want to specify a root route, which is your original question, you can just do root followed by the name of a controller, a hash sign (#), and the name of a class. So the code
root "application#hello"
means that a request to a url of the form /, or a root_path as it's called in rails convention, will get routed to the action (or method) named hello defined in a controller (or a class) named ApplicationController. You could accomplish the same result by doing
get '/' => "application#hello", as: :root
(you can name a route by adding as: :custom_name) but rails is smart enough to know that the two are equivalent. The task is made easier by following the rails conventions.
If you are completely new to Rails, I highly suggest you check out the Rails courses in Pragmatic Studio before going through the Ruby on Rails Tutorial which, as the author suggests, is not for a complete beginner. This approach worked perfectly for me. The rails courses offered by Pragmatic Studio assumes you have no prior knowledge about programming, and explains the basics in a manner much clearer than I did in this answer.
Happy coding :)

Ruby on Rails: partial view inheritance

I want to get next thing...
# For ArticlesController > ApplicationController
# in view
render 'articles/edit/form'
# tries 'app/views/articles/edit/_form.html.erb'
# then tries 'app/views/articles/_form.html.erb'
# then what it wants
Or maybe render with array partial option:
# For ArticlesController > ApplicationController
# in view
render_exists ['articles/edit/form', 'articles/new/form']
# tries 'app/views/articles/edit/_form.html.erb'
# then tries 'app/views/articles/new/_form.html.erb'
# then what it wants
This isn't realized, is this? But maybe some gems for 3.2 or monkeypatches... And don't you know pull requests to rails about it? Thanks!
UPD That's isn't controller-based view inheritance. This should work for (at the same page):
render `articles/edit/form`
render `comments/edit/form`
I'm using the mechanism I described in an article in the rails forum
It works a treat for me though I hear there is now some built in support in the latest versions or at least effort is under way to do add such a feature.
That already exists, and it's very similar to the controller inheritance.
You must follow a conventional strategy, however. You would put your global partial in app/views/application, then you can put a more specific one at each inherited level, like app/views/articles.
Take a look at the following railscast for more details: #269 Template Inheritance

Ruby on Rails match routing error

I'm trying to make a Rails application that serves simple static HTML pages. I followed Mikel's tutorial here (it involves making a Pages controller and setting up some routing) but I keep getting an error message.
I made a app/views/site/pages/_about.html.erb file to contain my About page. After starting the rails server, I try to go to http://localhost:3000/about/ but it gives me a Routing Error because I have an "uninitialized constant Site."
My project is uploaded to GitHub if you want to take a look at the code.
Edit: here's my config/routes.rb file:
NINAgallery::Application.routes.draw do
match ':page_name' => 'site/pages#show'
end
And here's the important part of my app/controllers/pages_controller.rb file:
class PagesController < ApplicationController
layout 'site'
def show
#page_name = params[:page_name].to_s.gsub(/\W/,'')
unless partial_exists?(#page_name)
render 'missing', :status => 404
end
end
# extra code for handling 404 errors goes here
end
site/pages#show means the show action in Site::PagesController
You either need to put your controller in the namespace your routes imply or change the route
The last line in the PagesController is this:
ValidPartials = Site::PagesController.find_partials
That means that the PagesController is contained in a Site module. But there is no Site module in your app.
I think simple removing Site:: should fix the problem:
ValidPartials = PagesController.find_partials
Plus the route:
match ':page_name' => 'pages#show'
Your application is called NINAgallery.
Replace Site in pages_controller.rb line 27 by NINAgallery.
PS:
I just took a peek at the so-called tutorial. You are taking really really really bad habits.
Some resources to take very good basics:
http://guides.rubyonrails.org/
http://api.rubyonrails.org/
If you like tutorials: http://ruby.railstutorial.org/
And there are plenty of books about rails. All good.
Besides the namespace problem, you also needed to add the 'app' Gem to the Gemfile, as explained in the tutorial.
I don't know why you removed the caching of the static pages in your working code. I made a pull request with the app working and maintaining the cache problem. If another person is interested, the code is here
Also ryan bates has a tutorial called "Semi static pages" that does something similar. I would encourage you to follow his solutions because there are very rarely mistaken.

error on rails 3

Hi this is ROR beginner's question.
I have creat controller.rb and view hello.rhtml following the tutorial, but when I try to open localhost:3000/say/hello, it come up with with error: No route matches [GET] "/say/hello"
could any one advice please?
Well you need to setup a route for that in your config/routes.rb file.
For first try i would say use a script generator, enter on the command line as being in the project library > rails g controller helloworld index. This will create a route for itself, and a controller file.
After this script runs, there should be a line in your config/routes.rb
Cloud::Application.routes.draw do
get "helloworld/index"
end
Then you need to enter localhost:3000/helloworld/index in your browser url bar. Then ( as default ) rails will render the view located in app/views/helloworld/index.*. If you want to change this behaviour, go to the helloworld controller.
For more info there is a useful guide: ROUTING GUIDES
You need to define a route definition so that the URL you are requesting gets mapped to an action in the controller you have created which would render hello.rhtml. Say your controller name is says_controller.rb (thats how Rails gives the filename). In that if you define and action hello which would by default render hello.rhtml, then the fallback routes which are defined in the routes.rb file at the end would make a request to say/hello to look for the say_controller and hello action, thus rendering hello.rhtml.
For detailed help you can refer to the Rails Guides. There is a lot of helpful material and it is explained very well.
I started developing RoR recently and the best practise I got was the tutorial # rails for zombies and video's # railscasts. I suggest you watch some / make some and you get a general idea how to get started :)
-edit- on this issue: You're trying to render the hello view from the say controller.
since routing is handled by default on :controller/:action, do you have a action called hello in say? No action means no route means no view rendered.
class SayController < ApplicationController
def hello
#do nothing or add some code
logger.debug "I'm in the say controller, hello action!"
end
end
This should get it to render the hello file. You might want to take a look at restful actions / crud though, rails uses those by default.

Blank page when navigating to http://localhost:3000/say/hello

I'm new to Ruby on Rails and am doing my first tutorial and am running the latest version of rails 3 and ruby 1.9.2. After creating my controller and navigating to http://localhost:3000/say/hello I'm receiving a blank page. I do see the Welcome to Rails message when I just go to http://localhost:3000. I've done some Google searches and people have similar problems but there is no clear fix. I've never really worked with MVC before so the concept of routing is fairly new to me.
Below is my controller:
class SayController < ApplicationController
def hello
end
def goodbye
end
end
My view:
<h1>Say hello to Rails!</h1>
You should delete the public/index.html file as that will mess with your routing and display by default. Have you set up your routes already, and what is the exact location and filename of the template?
You will need something like in your config/routes.rb file to correctly route that url to your template/view:
match '/say/hello' => 'say#hello'
First delete the index.html file from your public folder. Then, go to the app/views and check the views for the say controller. You should have a hello.html.erb.
The answer to your particular question was answered already by Bitterzoet, but I thought you might want some alternative learning resources.
I'm not sure which tutorial you're starting with, but I find it odd that they're not using RESTful routes. You can find out what routes you have set up at the moment by going to the console and typing "rake routes". If you would like a different tutorial, I recommend the one here:
http://www.wiki.devchix.com/index.php?title=Rails_3_Curriculum
I'd also recommend http://railsforzombies.org/ as a good first-time rails experience.
A fun general line to add to config/routes is:
match ':controller(/:action(/:id(.:format)))'
While developing, this will allow you to display the controller/action in address bar for ALL controller/action/id.format etc.
Like Bitterzote wrote, if controller is "say" and action is "hello", http://localhost:3000/say/hello .
If you use controller "say" and action "move", http://localhost:3000/say/move .
I've found this route to be very useful during development, but change this if you launch your application! (Rails warns: "Note: This route will make all actions in every controller accessible via GET requests.")

Resources