Rails Controller Action - ruby-on-rails

I wonder where those controller default actions defined. Even though I do not write the index action, the index view could be render! I used to read rails source code, but I can get where the method declares. I guess the actions is known by rails by the routes.rb . Anyone knows where I can find them in rails source code.

You could see in rails/actionpack/lib/action_controller/metal/implicit_render.rb
def method_for_action(action_name)
super || if template_exists?(action_name.to_s, _prefixes)
"default_render"
end
end
Rails will call default render when there is template even without you define action name.

Related

rails don't calls the engine's controller

I am trying to define some helper methods to be used in the app's controller, but it seems that rails don't even call the controller. just for the test I have the following controller in my app/controllers/my_engine/application_controller.rb and as the documents say rails should find it first and an error should raise because THIS_SHOULD_PRODUCE_ERROR is unknown, but the rspec happily executing without any errors!
class ApplicationController < ActionController::Base
THIS_SHOULD_PRODUCE_ERROR
end
I even tried to mimic the devise's way but the results are the same!
The guide section on the app directory suggests that the application_controller in an engine "will provide any common functionality for the controllers of the engine".
So I wouldn't expect that any additions to that controller will be available to all controllers in an application.
That also means that your application_controller is, I suspect, not getting called when you're running your test. Which would explain why you're not seeing an error.
In terms of how devise does it I think you need to be looking at how define_helpers works. The code you've linked to in your question is the application controller in the test app for the devise gem.
I noticed that I have got things wrong, and the application_controller in the engine does not get applied to application_controller in the app! Also, I couldn't figure out how the devise did it, but I have come up with the simple workaround for this:
require_relative 'controllers/helpers'
module Acu
module Injectors
class << self
ActiveSupport::Notifications.subscribe "start_processing.action_controller" do |**args|
eval((Acu::Configs.get :base_controller).to_s).class_eval do
include Acu::Controllers::Helpers
end
end
end
end
end
This will inject controller helpers to the user's base controller (which I get from the user, default: :ApplicationController) at the end of the class, which is perfect for me (but don't know how to add it to begging of the class if anyone needs it)

No Route Matches for a very basic Rails4 App

I'm very new to RoR and I'm trying to get a very basic site going. I have my home page working okay, but when I try to add a new page, I keep getting "No route matches" in the log. Here is the output from rake routes:
Prefix Verb URI Pattern Controller#Action
inventing_index GET /inventing/index(.:format) inventing#index
ideas_index GET /ideas/index(.:format) ideas#index
root GET / ideas#index
However, when I go to mysite.com/inventing or mysite.com/inventing/index I get the no route matches error. mysite.com/ shows the app/views/ideas.erb as hoped. All I did was rails generate controller inventing index. Is there something else I have to do to activate the route?
I'm running ruby 2.0.0p247 and rails 4.0.0 with passenger/apache on centos 6. I installed all the ruby/rails/passenger stuff, so its possible something isn't setup properly.
Thanks
EDIT: Here is my routes.db file:
Rortest::Application.routes.draw do
get "inventing/index"
get "ideas/index"
root to: 'ideas#index'
end
tldr: Your problem is probably the route. Change get 'inventing/index' to get 'inventing/index'=> 'inventings#index' to correctly point the route to your controller action.
There are four things you need to do when adding a new page/route. I usually do them in this order for static pages:
1) Create a controller with the appropriate action for each page
You already did this with rails generate controller inventing index, but make sure that:
In your app/controllers folder, you do indeed have a file called inventings_controller.rb
In inventings_controller.rb, you have at least this:
class InventingsController < ApplicationController
def index
end
end
2) Create a view for each controller action
Make sure that:
In your app/views/inventings folder, you have a file called index.html.erb
Puts some simple HTML in that file, like <h1>Testing123</h1>, just so you can see if it's working.
3) Add a route for each controller action
It looks like this may be the problem. In your routes.rb file, you'll need this:
get 'inventing/index' => 'inventings#index'
Your root to works because it's actually pointing directly to your controller action, but rails isn't smart enough to guess that inventing/index should go to the index action in your inventing**s** controller.
4) As others have suggested, restart your rails app
You can do this with ctrl+c at the command line, then rails s again to start it back up.

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

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.

How to change routes in ruby on rails?

I just installed Ruby on Rails and created a scaffold called posts. RoR generated controllers and other required files for me.
I created a new method in posts_controller, but I can't access it. I looked at other methods that are in the controller and looks like I need to access them by /posts/[MY POST ID]/[MY METHOD NAME].
Assuming I created my custom method hello in the controller, how do i access it?
I looked at routes.rb, but there's no configuration for it.
Updated:
I understand that I can manually configure it in routes.rb, but how do all the other methods work? For example, I have "edit", and "update" methods in the "posts_controller.rb" controller. How do those two methods work without configuring routes?
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
I can't find a configuration that matches /posts/[0-9]/edit pattern.
The documentation you're looking for is Rails Routing From the Outside In. Once you've read this you'll understand everything Rails does to take your request and point it at method in your controller.
You need to add a route for it to routes.rb. For example:
# Previous routes
# resources :posts
# Updated routes
resources :posts do
get "hello", :on => :member
end
Have a look at this Rails guide about routing, it should help you understand Rails routing.
This will give you a good head start on the routes: http://guides.rubyonrails.org/routing.html
Not every method you make will have its own path, rails is built on the rest principle, and your scaffold created methods in the post controller that follow those paths, like index, show etc....
You can force your method to have a route added to it, but in reality you rarely actually need to do so as following the convention is far easier.
In Rails 3.x
match 'posts/hello' => 'posts#hello'
Available at example.com/posts/hello
When you used scaffold to generate post, it added a line resources :posts in your routes.rb file. That line configures routes for all the controller actions that were generated. As Caleb mentions above, not every action has a dedicated path. A single path can correspond to multiple actions because rails also takes into account the HTTP method. So, for instance, the path /posts with the HTTP method GET corresponds to the controller action index, while the same path with the HTTP method PUT corresponds to the controller action update. You can see these associations when you run rake routes from the console. I agree with Jordan and Caleb that the Rails Guides is a good read and will help you understand routes.

Resources