Undenfined local variable or method when the view call a method - ruby-on-rails

I'm trying give a "Welcome Message" to my users with that:
#welcome_controller.rb
class WelcomeController < ApplicationController
def hi
#current_user
if (#current_user)
#welr = '¡Bienvenido' + current_user + ' a nuestra web!'
else
#weli = "¡Bienvenido invitado, no dude en registrarse!"
end
end
end
#hi.html.erb Only the call
<%= hi %>
When I initialize my server the controller give me this message:
undefined local variable or method `hi' for
I have tried many wways of repairing this but I can't.

You need to define hi as a helper_method in your controller. Something like
class WelcomeController < ApplicationController
helper_method :hi
def hi
# your stuff here...
end
end
See http://apidock.com/rails/AbstractController/Helpers/ClassMethods/helper_method for more info

That's not how you use controller methods. In Rails, methods defined on a controller are used to 'set up' the data needed for a particular view, or to handle a given request. They're not supposed to be called directly by a view.
For what you're trying to do, you need to add a helper method to WelcomeHelper. So, assuming you want http://yourapp.dev/welcome/ to output the message above, this is what you'd need:
# app/controllers/welcome_controller.rb
class WelcomeController < ApplicationController
def index
# Explicitly defining the `index` method is somewhat redundant, given
# that you appear to have no other logic for this view. However, I have
# included it for the sake of example.
end
end
# app/views/welcome/index.html.erb
<%= greeting %>
# app/helpers/welcome_helper.rb
class WelcomeHelper
# All methods in WelcomeHelper will be made available to any views
# that are part of WelcomeController.
def welcome
if (#current_user)
# You may need to change this to something like `#current_user.name`,
# depending on what #current_user actually is.
'¡Bienvenido' + #current_user + ' a nuestra web!'
else
"¡Bienvenido invitado, no dude en registrarse!"
end
end
end

This article may help you :
Ruby on Rails: Accessing Controller Methods from Your View
Just write:
<% #controller.hi %>

Related

Undefined method when calling Helper methods in rails

I have the following helper
module AvatarHelper
# Todo: set a defatul profile-image-path
DEFAULT_PROFILE_IMAGE_PATH = "http://image_here"
def avatar_path(user, size = 24)
..
end
def get_facebook_profile_pic user, size
..
end
def get_gravatar_path user, size
..
end
end
When I try to call the helper method in controller, it results in the following error:
undefined method `avatar_path' for AvatarHelper:Module
Here is my controller for reference:
class DashboardController < ApplicationController
before_action :authenticate_user!
def index
#dashboard = Dashboard.new(current_user)
puts AvatarHelper.avatar_path(current_user)
end
end
When I reference other helpers, I see they don't need to reference the helper elsewhere.
module TitleHelper
SITE_TITLE = 'My Site'
TITLE_SEPARATOR = ' · '
DESCRIPTION_CHARACTER_LIMIT = 140
def title(*parts)
parts << SITE_TITLE
provide(:title, parts.compact.join(TITLE_SEPARATOR))
end
end
I can then just add the title method directly in the view.
<% title 'myPage' %>
Module methods cannot be invoked directly. They should be included in the class to invoke. That's why they are called mixins(they can be mixed with others).
Here you can include the module in your controller.
class DashboardController < ApplicationController
include AvatarHelper
def index
#dashboard = Dashboard.new(current_user)
puts avatar_path(current_user)
end
end
def self.avatar_path(user, size = 24)
..
end
you are calling instance method add self before mthod will work for you.
Add the following code in your helper.
module AvatarHelper
extend ActiveSupport::Concern
Now you can directly call your method by name like
puts avatar_path(current_user)

Method Defined in Controller Throwing NoMethodError

My application has Dwellings and Roomies. I am building some authentication into the Dwelling view - only users who are roomies of the current dwelling should be able to view certain data - all other users will see a different view.
To enable this, I have created an is_roomie? method in the Users Controller. The method looks like this:
## is_roomie? method in Users_Controller.rb ##
def is_roomie?
roomie_ids = []
#dwelling.roomies.each do |r|
roomies_ids << r.id
end
roomie_ids.include?(current_user.id)
end
I call this method in the Dwelling view as follows:
## show.html.erb (Dwelling) ##
....
<% if current_user && current_user.is_roomie? %>
....
When I loaded the page after implementing this, I get the following NoMethoderror:
NoMethodError in Dwellings#show
Showing >/Volumes/UserData/Users/jraczak/Desktop/Everything/rails_projects/Roomie/roomie/app/views/dwellings/show.html.erb where line #5 raised:
undefined method `is_roomie?' for #User:0x00000102db4608>
For some background, I did try this as a Dwelling method and moved this into the User model to no avail. Thanks in advance for any and all insight!
current_user is a User object, not a UsersController object, so you cannot call the method you've defined on that object. When you think about it in this context, you'll see that you should define this method on User.
Try something like this in app/model/user.rb:
class User < ActiveRecord::Base
# ...
def roomie?(dwelling)
dwelling.roomies.include?(self)
end
end
Looking at this, though, we can improve the code by moving it into the Dwelling class in app/models/dwelling.rb:
class Dwelling < ActiveRecord::Base
# ...
def roomie?(user)
roomies.include?(user)
end
end
You would then use this in the view with:
<% if current_user && #dwelling.roomie?(current_user) %>
The current_user object does not have a method is_roomie?. This is a method in your controller. You can call the method in your show action and make it available for the view like so:
#in UsersController.rb
def show
#is_roomie = is_roomie?
end

Adding custom internal method to a controller

I'm new with RoR and I have a controller (UsersController) where I wish to verify the existence of a certain session before anything. Since the session verification code is the same for several methods and I don't want to repeat myself, I decided to make a new method in my controller to check the sessions:
class UsersController < ApplicationController
def index
end
def show
end
def new
if self.has_register_session?
# Does something
else
# Does something else
end
end
def edit
end
def create
end
def update
end
def destroy
end
def self.has_register_session?
# true or false
end
end
And when I run the page /users/new, I got this error:
undefined method `has_register_session?' for #<UsersController:0x1036d9b48>
Any idea?
self when you define the method refers to the UsersController class object, but within the instance method new, self refers to the instance of UsersController.
You can either make your method an instance method:
def has_register_session?
# code
end
You can then get rid of the self when calling has_register_session? in new as well.
Or call the method on the class:
if UsersController.has_register_session?
# code
end
instead of referencing UsersController explicitly you could do self.class.
Note that you likely want the first solution: making has_register_session? an instance method.
By doing def self.blah you've created a class method whereas you want an instance method.
You might also want to make the method protected - all public methods are exposed as actions by default.

Helper Class not Accessible from View

I defined a helper class as below
module SessionsHelper
def current_user
#current_user= User.find_by_fbid(session[:fbid])
end
def sign_in(user)
session[:fbid] = user.fbid
#current_user = user
end
def signed_in?
!current_user.nil?
end
end
I included the Helper Class in my Application Controller
class ApplicationController < ActionController::Base
protect_from_forgery
include SessionsHelper
end
The sign in method gets called from Session Controller
class SessionsController < ApplicationController
def create
user = User.find_or_create_by_fbid(params[:user][:fbid])
user.update_attributes(params[:user])
sign_in(user)
redirect_to user_path(user)
end
end
However I am not able to access 'current_user' variable from users#show view.
<% if signed_in? %>
<p>
<b>Current User:</b>
<%= current_user.name %>
</p>
<% end %>
It says : undefined method `name' for nil:NilClass
Can anyone please advise ?
The method current_user does not get called at all from index.
Putting include SessionsHelper in your controller includes those module methods in the controller, so they are accessible in your controller methods. You want the helper methods available in your views, so you need to use helper SessionsHelper in your application controller.
That being said, I do agree with Jits that the methods you have in SessionsHelper really do belong in the controller instead of in a helper.
Generally you should have methods like current_user defined in your application_controller and then make them available as helpers in the views. This way the controllers have access to them (and trust me, you will most likely need access to things like that). Example:
def current_user
..
end
helper :current_user
What helped me:
Define methods to use in the controller in helper files
Define methods to use in the view in the relevant model file
Example
Suppose you had this in user_helper.rb
def something
2 + 2
end
simply move that code into
models/user.rb
and it will be accessible in the view without any further effort.

calling methods dynamically inside a controller

I have the following scenario
I want to add methods dynamically to a controller. All my method names are in a table . Please refer the following example
-table (method_names)-
1 - Walk
2 - Speek
3 - Run
and I have a controller
class UsersController < ApplicationController
def index
end
end
Inside this index action i want to call my methods dynamically. Those methods were actually implemented else ware.
I have another controller like
class ActionImplementController < ApplicationController
def walk
puts "I'm walking"
end
def speek
puts "I'm sppeking"
end
def run
puts "I'm running"
end
end
** I have done something like below and its working
class UsersController < ApplicationController
def index
a = eval("ActionImplementController.new.run")
end
end
But my question is , is this the right way or is there anyother way to do this
Thanks in advance
cheers
sameera
While the first answer works, i would prefer something like this
module ImplementsActions
def run
...
end
def walk
..
end
def ...
end
and then in your controller write
class UsersController < ActionController::Base
include ImplementsActions
# now you can just use run/speek/walk
def index
run
end
end
Much cleaner because the code can be shared, but it is defined where you need it.
I think it's generally best to avoid the use of eval. If you can, I would make all your methods class methods and then run them like so:
def index
ActionImplementController.send :run
# ActionImplementController.new.send(:run) works if you can't use class methods
end

Resources