How do I tell if the current action is in an Engine? - ruby-on-rails

Within my application.html.erb, I want to be able to detect if the currently rendering page is from within a mounted engine (Forem, if that matters), so that I can add an active class to the nav bar. Is there an easy way to detect this?
I'm using Rails 3.2.

You could add a helper method in Forem::ApplicationController by reopening the class:
Forem::ApplicationController.class_eval do
def forem?
true
end
helper_method :forem?
end
Add the above file in app/decorators/forem/application_controller_decorator.rb for example.
This way every time a view is rendered by Forem's controller you would be able to call forem? within your view.
application.html.erb
<% if forem? %>
# do something
<% end %>
You might want to check if the current instance respond_to?(:forem?) first, or add a forem? method returning false in your own application_controller.rb.

A very similar approach can be done without the use of decorator loading (just using Rails default loading), e.g. for Thredded:
#This file would be at app/controllers/thredded/application_controller.rb in your main_app repo
require_dependency File.expand_path("../../app/controllers/thredded/application_controller",
Thredded::Engine.called_from)
module Thredded
class ApplicationController < ::ApplicationController
def thredded?
true
end
end
end
and then add the default value and helper_method declaration in your own ApplicationController:
class ApplicationController < ActionController::Base
helper_method :thredded?
def thredded?
false
end
# etc
end

You can use this:
<% if controller.controller_name == ""something" &&
controller.action_name == "something" %>
Do someting <!-- add you class -->
<% end %>

Related

How to check where currently used controller inherits from?

In my Rails 7 application I've got two controllers:
class Context::FrontendController < ApplicationController
end
class Context::BackendController < ApplicationController
end
All my other controllers (and there are a lot of them) inherit from either the first one or the second one (but never both).
In my views I sometimes need to show or hide certain elements depending on if the current controller inherits from the FrontendController OR the BackendController.
How can this check be done?
In my views I sometimes need to show or hide certain elements depending on if the current controller inherits from the FrontendController OR the BackendController.
How can this check be done?
You can do this check (as shown by #mechnicov), but you shouldn't. Instead, use OOP.
class ApplicationController
def current_area
# raise NotImplementedError
:none
end
helper_method :current_area
end
class FrontendController < ApplicationController
def current_area
:frontend
end
end
class BackendController < ApplicationController
def current_area
:backend
end
end
Then
<% if current_area == :frontend %>
You can prettify this as you wish (make methods frontend? / backend?, etc.)
In your view you can use something like
<% if controller.class.ancestors.include?(Context::BackendController) %>
<%= show.some.content %>
<% end %>
May be create some helper
def inherited_from?(controller_class)
controller.class.ancestors.include?(controller_class)
end
And then
<% if inherited_from?(Context::BackendController) %>
<%= show.some.content %>
<% end %>

access application controller in view rails

I am having a action in application controller
def is_customer_logged_in?
!!session[:customer_id]
end
And in my view am trying to access the application_controller action like this
<% unless is_customer_logged_in? %>
some functions
<% end %>
The above code is a partial layouts.
This is the error message I am facing
undefined method `is_customer_logged_in?' for #<#<Class:0xb51a5300>:0xb5616484>
You can define it to be a helper method and you should be able to access that method in the view.
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
def is_customer_logged_in?
!!session[:customer_id]
end
helper_method :is_customer_logged_in?
end
try helper_method: is_customer_logged_in?

Ruby on rails: How can I get values from a database in application.html.erb?

How can I get values from database in application.html.erb? I need to get those values for whole project. Those values will stay forever to all pages. How can I pass values to application.html.erb?
Is there anything like beforeRender?
Is there anything like appcontroller.rb to override actions?
You could use an application wide before_filter - like so
class ApplicationController < ActionController::Base
before_filter :load_application_wide_varibales
private
def load_application_wide_varibales
#var = Model.where :condition => "whatever"
end
end
#var would then be available in all your views
cheers
you can put method in the application controller
before_filter :load_data
def load_data
#data = Data.all
end
All controllers inherits ApplicationController, so data will be loaded at all actions. Now you can use #data at you application.html.erb file
The best way is probably to create a method in your application controller and declare it a helper method. Then you can call that method in application.html.erb. For example if you want to be able to use the current user throughout your application you'd do something like this:
class ApplicationController
helper_method :current_user
def current_user
#current_user ||= User.find(session[:user_id])
end
end
Then in application.html.erb you can do the following:
Hello <%= current_user.name %>
It's also possible to use before_filter like to other answers suggest, but in this solution the database only gets hit when it's necessary. With before_filter it always gets hit.

Undenfined local variable or method when the view call a method

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 %>

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.

Resources