Is there a way to check if there exists an index action for a controller? Something like:
Controller.indexActionExists?
I have seen posts to check if specific routes exist, but those methods aren't working for me, since some of my index actions aren't associated with routes.
The action_methods method is going to be the most expedient tool in this case, returning a Set of method names. Give the following code a shot:
# Get a set of method names belonging to a controller called 'MyController'
methods = MyController.action_methods
if methods.include? "index"
puts "MyController has an index method"
else
puts "MyController lacks an index method"
end
Related
Rails 3.2.18
Ruby 2.1.5
In my controller, I have new and create methods. I have another method in the controller, let's call it post_create that I would like to automatically trigger after the create method finishes executing. This method has no view associated with it, and it's supposed to update a table.
I tried doing
after_filter :post_create, only:[:create]
But I need the parameters that were passed to the create method, and at this point I no longer have them. Any ideas?
It can be done in this way:-
def create
#code
redirect_to post_create_path(parameter)
end
def post_create
#update the table
redirect_to desired_path
end
Note:- Set the path by knowing the routes by typing in the console as rake routes.
You will get params in you after_action. If this is not the case. You can perform such action in observer. If this is something that does not affect your new view. Then you should go for observer instead of creating a after_action. For mor detail check here.
The scenario is this:
I have 2 Model-View-Controllers , A and B.
In A's index.html.erb, I have a link to B's new.html.erb, that looks like /a/1/b/new. B can also be displayed by doing /b/new.
In B's new method is there a way to tell I got there from a?
I need to do if came from A, do some, otherwise don't.
Thanks
You can use the refer
refer_hash = Rails.application.routes.recognize_path(request.referrer)
now you can check the previous controller by
refer_hash[:controller]
and action by
refer_hash[:action]
So in the end you will have code like
refer_hash = Rails.application.routes.recognize_path(request.referrer)
if refer_hash[:action] == 'index' && refer_hash[:controller] == 'A'
# Do something
else
# Do something else
end
If your action is processing the request with A resource, you should be able to retrieve the a_id in the params hash. Here is the method I often use in my app:
class BController < ApplicationController
def new
if params[:a_id].present?
#do something with A here
else
#do something otherwise
end
end
end
If you want to be sure, run rake routes in your console to see how the requests look like. I imagine you would see a route like this:
a/:a_id/b/new
and another route like this
/b/new
FYI
If you'd like to know the name of your controller & action, you can use the two Rails helpers called action_name (now action it seems) and controller_name
Whether this will help you directly, I'm not sure
--
Referral
In B's new method is there a way to tell I got there from a?
I don't know if this will solve your issue as well as #sonnyhe2002's answer, but if you're requesting B from a nested resource, you could play with the params hash to achieve the functionality you desire
If your routes are like this:
#config/routes.rb
resources :a do
resources :b #-> domain.com/a/:a_id/b/new
end
This will mean if you render the b#new action as part of your nested route, you will have the variable params[:a_id] available, which means you'll be able to test if it's there in your b controller action:
#app/controllers/b_controller.rb
def new
if params[:a_id]
# logic
else
# logic
end
end
It's a different way of looking at it
I am using ruby on rails to make a simple social networking site that includes different message boards for each committee of a student group. I want the url structure for each board to look like https://<base_url>/boards/<committee_name> and this will bring the user to the message board for that committee.
My routes.rb file looks like:
resources :committees, only: [:index]
match '/boards/:name', to: 'committees#index(name)'
My index function of committees_controller.rb file looks like:
def index(name)
#posts = Committee.where(name: name)
end
And then I'll use the #posts variable on the page to display all of the posts, but right now when I navigate to https://<base_url>/boards/<committee_name> I get an Unknown Action error, and it says The action 'index(name)' could not be found for CommitteesController.
Could someone guide me through what I have done wrong?
Once I get this working, how would I make a view that reflects this url structure?
Set up your routes like this:
resources :committees, only: [:index]
match '/boards/:name', to: 'committees#show'
and the controller like this:
def index
#committees = Committee.all
end
def show
#committee = Committee.find_by_name!(params[:name])
end
You can't really pass arguments to controller actions the way you were trying to with index(name). Instead, you use the params hash that Rails provides you. The :name part of the route declaration tells Rails to put whatever matches there into params[:name].
You also should be using separate actions for the listing of committees and displaying single committees. Going by Rails conventions, these should be the index and show actions, respectively.
When routing, you only specify the method name, not the arguments:
match '/boards/:name', to: 'committees#show'
Generally you will declare something with resources or match but not both. To stay REST-ful, this should be the show method. Index is a collection method, usually not taking any sort of record identifier.
Arguments always come in via the params structure:
def show
#posts = Committee.where(name: params[:name])
end
Controller methods that are exposed via routes do not take arguments. You may construct private methods that do take arguments for other purposes.
I have a function to take ownership of a job which updates the database to update the username in a table row. I want to link to this function from the view and then redirect to the appropriate page.
How do you link to a controller function or a model function from the view?
from the index i want to have another link beside show, edit, delete, which says 'take ownership'
This will then fire off an action in the application controller
def accept_job(job_type, id, username)
if (job_type == 'decom')
Decommission.update(id, :username => username)
else
end
end
You can use the instance variable #controller to get a reference to the controller. As for calling a model function, you can call Model.function to call class methods, or if you have a particular Model instance called model_instance, then use model_instance.function to call an instance method.
Edit: Okay, I think I understand what you're asking now.
You should
Create a new action in the controller, let's call it update_username:
def update_username
job = Job.find(params[:id])
job.your_method #call your method on the model to update the username
redirect_to :back #or whatever you'd like it to redirect to
end
Add your action the routes in routes.rb. See Rails Routing from the Outside In for more details.
Add your link in the view:
<%=link_to "Update my username please!", update_username_job_path%>
First you create a function in your model, say
class Decommission
def assign_permission(name)
#your update code
end
end
As I can see, you can do this in 3 different ways
1 - Create a helper method to update the permission (This can be done either in Application helper or helper related to your view)
2 - By creating a controller method (as you proposed) But if you are not using this method in other views you dont need to create this method in application controller
3 - If you want to use your method in both controllers and views, create your method in application controller and make it as helper method. By that way you can access it from controllers as well as views
cheers
sameera
In runtime we can get the current controller and current action names by controller_name and action_name methods like wise,
I want to get all the remaining controllers and action names and models too if possible..
Any rails method available to get all the controller names and the action names in application controller.
#table_names = ActiveRecord::Base.connection.tables
#model_names = Array.new
#model_names.each do |table_to_model|
#model_names = #model_names.insert(#model_names.length,table_to_model.camelize.singularize) unless table_to_model.blank?
end
This is how you get all Model name