I am working on a project which involves understanding the mechanism of how rails does rendering and layouts, including, where does rails know that it needs to do rendering (either by a render statement or default rendering), which view file it is going to render, how is view file nested together, how does rails merge the layouts with the view file, how does rails decide which layout file to use for a specific render statement. I hope there are some existing code module I can use to produce such rendering results, so I don't have to write code to mimic this process myself.
Backing what the Tin Man said, I'm gonna do my best to answer this as 'How does rendering views work'
First you create a controller....
rails g controller welcome index
This creates the welcome controller with the action index
By action, I mean if you look inside the new welcome controller you will see
def index
end
That's where all the variables and stuff go that you need inside of that 'page' for example if you need to print out all the users, you would do this
def index
#users = User.all
end
Now, inside of /config/routes.rb, when you typed in rails g controller welcome index it generated a route something like this
get '/welcome/index' => 'welcome#index'
What that does, is when someone goes to the URL http://localhost:3000/welcome/index Rails will point to the welcome controller and render the index action
What that will do is tell rails, 'HEY, theres an action called index, go look in /views/welcome and make sure there's a file called index.html.erb
That WILL be there because when you generated the controller, it generates the views for the actions you specify, in this case we only specified index.
Now Rails knows what controller to look in and what action and html to render.
That's pretty much the basics :)
Hope this helps!
Related
As I understand it, routes will take you from a starting point to a controller, and an action. The action brings up the associated views; so what if I don't need any views for my controller, and just want to just call a controller's underlying method, without rendering the view or route.
Lets say I have a FoodsController with several methods, and there exists methods cake, pizza, and chips within that controller. Each one queries the database for a secret message and stores it in a variable, but the request for this is going to come from some other part of our application.
To accomplish this am I supposed to use a route for this or some kind of dot syntax such as food.cake().
So I guess what I am trying to say is, hey "Server" go do this and come back to where you left off once its done.
Controller are only for URL endpoints. For example if you hit http://my.app/my_route, you need to map the my_route part to a controller action in your routes.rb file. But what happens if you type this into your browser? You'll want to see something right? So you need to return some data (json, html, erc). You can use render for this.
This is different to writing 'normal' Ruby code, i.e. Ruby outside a web framework. Do you understand what a class is and how the following works?
class MyClass
def initialize
end
def my_method
puts "my_method_called"
end
end
MyClass.new.my_method # => "my_method_called"
This is very basic Ruby and works in Rails as well, although there are some rules about where code needs to be written.
By the way, if you really want to make a controller action that renders nothing, just use:
render text: "", status: 204
return false
The status: 204 means "No Content".
You can use render json or text, if the method does not render anything, I think it should be private.
In your example you could use the cake method in another controller like so:
cake = Food.cake
Please note that this method should live in the food model and not the controller, since you do not need a view.
Iam new in Ruby on Rails. Normally I work with other web languages and now (of course) I try to compare it with other languages using on web.
But sometimes i have some problem to understand the philosophy and the character of Ruby on Rails. Of course i understand the concept of MVC.
But now Iam not absolutely sure:
Is ist OK to create and use a controller without views? In some cases you need a "class" for some usefull functionality used by other controllers they have views. Or is it a better style to use a module?
I try to find it out by reading a lot of articles and examples, but didnt find detailed information about this content.
When developing Ruby On Rails apps, it's recommended to put most of your business logic in the models, so for the controllers the logic need to be minimal to provide info for the views, so if it doesn't work with a view chance that you need a controller are really low.
Is it OK to create and use a controller without views
Yep it's okay.
The key thing to keep in mind is that Ruby/Rails is object orientated.
This means that every single you do with your controllers/models etc should have the "object" you're manipulating at its core.
With this in mind, it means you can have a controller without corresponding views, as sometimes, you just need to manipulate an object and return a simple response (for example with Ajax).
--
We often re-use views for different actions (does that count as not having a view):
#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
def search
render :index, layout: false
end
end
The notion of skinny controller, fat model is sound in principle, you have to account for the times when you may need small pieces of functionality that can only be handled by a controller:
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def update
#user = User.find params[:id]
#user.update
respond_to do |format|
format.js {render nothing: true}
format.html
end
end
end
A very rudimentary example of Rails is a drive-thru:
view = input interface
controller = accepts order & delivers
model = gets order packaged etc in backend
There are times when the controller may not need a view (for example, if you update your order with specific dietry requirements), and thus the notion that every controller action has to have a view is false.
It's really about making your controller versatile enough to manage your objects correctly.
Shared controller methods can be placed in ApplicationController. Also, in Rails 4 there are concerns (app/controllers/concerns/) where you can put the modules with methods that can be used by multiple controllers.
Controller handles request and renders corresponding view template. So controller without view is absolutely nonsense.
Every time request will execute this controller, it will just end with missing template error, so you will need to create view folder and put empty files with action name inside of it, which is obviously stupid.
I'm trying to implement the following behavior:
You can see that i have pretty standart views structure for controller, but instead "actions" partial, i created folder which is named like an action and in them i have a partials for actions.
I Try use "prepend_view_path":
def set_view_paths
self.prepend_view_path ["#{Rails.root}/app/views/#{controller_name}/#{action_name}"]
end
But rails finds next:
Missing template "posts/index"
in ".../app/views/posts/index"
I need to add somthing like that in the end of the action:
render template: 'index'
Question:
Is there a more beautiful way to solve this problem?
Checkout this SO thread. From reading the thread it doesn't look like there is a clean way for you to solve this problem. The only way would be to override render.
I'm not sure why you are putting your template files into subfolders but, if it is not providing you with any benifit, it's probably easier to move index.html.erb, show.html.erb ect out of their subfolders and just put them under views/posts.
This will also make it easier for other developers (and yourself, later on) because you are conforming to Rails conventions.
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
The first layer is routing and the second layer the controller, so when in View, is there a way to dump out the path or filenames and line numbers of route and controller before reaching view?
I wanted to do this because www.example.com/stories/12345 is showing a page, but stories_controller.rb doesn't have a def index or def show
Update: I guess it might be as if the program has an error, in which case it will show an application trace and a rails trace.
Well actually there is no other alternative than using a index or show and it has to be defined inside the class StoriesController. But it does not mean that those methods are defined inside the file "stories_controller.rb".
There are a few options:
they are defined in the ApplicationController from which it derives. Or there is another parent-class.
for instance, when you use ActiveScaffold your controller contains a single line active_scaffold that adds all the standard CRUD actions (index, show, ...)
To see where a method is defined, you could type inside your script/console session
StoriesController.new.method('index')
and it would return a set of classes/modules, as explained here.
For instance, in our ApplicationController we include a module that defines a method login_required, and that looks like this:
>> ApplicationController.new.method(:login_required)
=> #<Method: ApplicationController(PilgrimBase::Base::Authenticated)#login_required>
Hope this helps.
I know this doesnt really answer your question, but ...
you can see your routes by doing
rake routes
do you have show.html.erb in your app/views/stories/ ?