I call a method on controller A that renders a jbuilder template (a file called signed_in.json.jbuilder). Inside the template I want to call a method, friendsCount, that is in controller B. I'm getting an error when I try to access the controller B method inside the template. The error is:
NameError - undefined local variable or method `friendsCount' for #<#<Class:0x007f90a09994f8>:0x007f90a0998788>:
app/views/api/sessions/signed_in.json.jbuilder
I thought that adding helper_method: friendsCount to controller B should solve exactly the type of issue I want to solve: making a controller method available in views.
Actually, when I try to access a method from my ApplicationsController in my jbuilder template (controller C below), I have no issue.
Here is my code:
CONTROLLER A:
class Api::SessionsController < ApplicationController
def create
#user = User.find_by_credentials(session_params[:username], session_params[:password])
if #user.nil?
render json: ["couldn't find user"], status: 404
else
sign_in!(#user)
render :signed_in
end
end
private
def session_params
params.require(:session).permit(:username, :password)
end
end
JBUILDER TEMPLATE: signed_in.json.jbuilder
json.friendsSorted sortFriends
json.friends friendsCount
CONTROLLER B
class Api::FeedsourcesController < ApplicationController
helper_method :friendsCount
def friendsCount
friendsCountHash = {}
# ... populate friendsCountHash
render json: friendsCountHash
end
CONTROLLER C
class ApplicationController < ActionController::Base
helper_method :sortFriends
def sortFriends
#...
return sortedFriendsArray
end
end
I do not want to have the friendsCount method in the helpers folder because I also need to be able to have a direct controller route to this method for other purposes.
You need to have helper methods in the calling controller or its superclass.
In your case it's SessionsController and ApplicationController.
FeedsourcesController is not superclass for SessionsController, so view renderer do not know about any methods in it.
Related
I have an action:
def test
_process_action_callbacks.map { |c| pp c.filter }
render json: {hello: 'world'}
end
That for some reason is calling my current_user function defined in my application controller.
At first I thought it was a before action that was calling my current_user function (hence _process_action_callbacks). But after stripping away all of my before actions the call remained. The only two before actions are part of rails:
:clean_temp_files
:set_turbolinks_location_header_from_session
I used caller to see where my method was getting called from. Here's the stacktrace (and method declaration):
def current_user
pp caller
# get the current user from the db.
end
As you can see, the current_user function is being called by the serialization_scope method in the serialization class. How do I prevent it from calling my current_user function?
Your tag indicates you are using active-model-serializers. By default current_user is the scope. To customize the scope, defined in the application-controller, you can do something like
class ApplicationController < ActionController::Base
serialization_scope :current_admin
end
The above example will change the scope from current_user (the default) to current_admin.
In your case, you probably just want to set the scope in your controller (I assume it is called SomeController ;) ) you can write
class SomeController < ApplicationController
serialization_scope nil
def test
render json: {hello: 'world'}
end
end
See for complete documentation: https://github.com/rails-api/active_model_serializers/tree/0-9-stable#customizing-scope
I am trying to access helper method in my controller using helpers like below:
class MyController < ApplicationController
def index
#foo = 'bar'
helpers.my_helper_method
end
end
Inside Helper method, I am trying to access an instance variable of controller
module MyHelper
def my_helper_method
#some manipulation on foo
#foo.to_i
end
end
But in above scenario #foo is nil. When I call the same method from view, #foo is available. So the instance variable can be passed to helper method only through UI or some other way is there?
Thanks in advance.
UPDATE:
view_context
seems like reasonable solution https://apidock.com/rails/AbstractController/Rendering/view_context
class MyController < ApplicationController
def index
#foo = 'bar'
helpers.my_helper_method(#foo)
end
end
module MyHelper
def my_helper_method(foo)
#some manipulation on foo
foo.to_i
end
end
pass it as argument.
You can access instance variables that you set in a controller in your helpers. If the value is nil, then you need to deal with it in your helper:
module SomeHelper
def do_something
return 0 if !#value
value * 3
end
end
class SomeController
def index
#value = 1
helpers.do_something
end
def show
#value = nil
helpers.do_something
end
end
is it necessary to mention the private methods in controller as helper_methods in controller?
Like
class PostsController < ApplicationController
helper_method :check_something
def new
check_something
#post = Post.new
end
def show
#post = Post.find(params[:id])
end
private
def check_something
redirect_to(root_path) and return if something
end
end
Is the statement : helper_method :check_something required ? if so why ?
And when i call a private method from a controllers action method is the params hash accessible in the private or the helper method ??
I think you have misunderstood the 'helper_method' concept.
helper_method is used to make your controller method to act as a method as its in your helper modules
So inside your controller, you can always access your private method without the 'helper_method' section
and if you add a controller method as a helper method, as you have already done, in your view you can simply call it
and for your second question, yes params hash is accessible via controllers private methods
HTH
No it is not necessary. You can always call private methods of your controller within your controller.
Also, params would be available automatically for the private methods within controller.
No need to mention a private method as helper method in your controller. You can directly call them from another methods from the same controller by passing parameters like params, or any thing.
class ContorllerName < ApplicationController
def index
private_method(params)
end
private
def private_method(vals)
vals
end
end
I'm trying to create a custom helper like this:
# app/controllers/my_controller.rb
class MyController < ApplicationController
helper :my
def index
puts foo
end
end
# app/helpers/my_helper.rb
module MyHelper
def foo
"Hello"
end
end
But, I got the following error:
undefined local variable or method `foo' for #<MyController:0x20e01d0>
What am I missing ?
Generally, I do the opposite: I use controller methods as helpers.
class MyController < ApplicationController
helper_method :my_helper
private
def my_helper
"text"
end
end
Helpers are accessed from the views, not the controllers. so if you try to put the following inside your index template it should work:
#my/index.html.erb
<%= foo %>
If you do want to access something from the controller, then you should use the include syntax instead of helper, but do not name it like a helper module in that case.
How about just including the helper as a mixin in the controller...
class MyController < ApplicationController
include MyHelper
def index
puts foo
end
end
I created a helper method for some simple calculation. This helper method will just return an integer. I need the helper in both controllers and views.
Unfortunately, it work well in views but not in controllers. I get the undefined local variable or method error. How can I fix it?
Thanks all
In order to use same methods in both controller and views Add you method in application_controller.rb and make it helper methods.
For example
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
#protect_from_forgery # See ActionController::RequestForgeryProtection for details
helper_method :current_user
def current_user
session[:user]
end
end
Now you can use method current_user in both controllers & views
I use a following solution. Because I think helper's methods shoud be stored in an appropriate helper module.
module TestHelper
def my_helper_method
#something
end
end
class SomeController < ApplicationController
def index
template.my_helper_method
end
end