Rails: Sidebar Conflict - ruby-on-rails

I've a sidebard to display #notices
<% #notices.each do |notice| %>
<li class="list-group-item notice"><%= short_auto_link(notice.content) %></li>
<% end %>
I also have a admin interface to manage notices(e.g. CRUD).
The problem is that when I open edit or new page for notice.
It will report undefined method 'each' for nil:NilClass for <% #notices.each do |notice| %>.
Now I can only get away with this by adding a <% if #notices %> before the .each block.
UPDATE:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_filter :set_notice
def set_notice
#notices = Notice.all
end
end
app/views/notices/_notice_board.html.erb:8:in `_app_views_notices__notice_board_html_erb__624099781_29657256'
app/views/layouts/application.html.erb:19:in `_app_views_layouts_application_html_erb___900927418_28913616'

You need to change this:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_filter :set_notice
def set_notice
#notices = Notice.all
end
end
to this:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_filter :set_notices
def set_notices
#notices = Notice.all
end
end
Things you can learn from this is that always try to avoid such naming conventions of a method. Since, you're setting #notices(plural), your method name should also be plural: set_notices. In your case set_notice method is being overridden by method defined with the same name in NoticesController. Changing the method name as mentioned above should fix the issue.

If your sidebar is shared only across all actions of your admins_controller define a private method to get #notices in admins_controller, and put before_filter at the beginning of the controller.
in admins_controller ::
before_filter :prepare_notices
def show
end
def edit
end
...
private
def prepare_notices
#notices = YOUR_QUERY
end
If your sidebar will be rendered across the whole website move the code to your application_controller and before any request to you server this method will be executed.
If your sidebar will be rendered with some actions in your website you should put the get_notices method in the application_controller and use before_filter in each controller specifying the actions that will render the sidebar only.

Related

NoMethodError in Admin::DashboardController#index

am new to rails, and am using active admin for a work, and i get this error whenever i open active admin dashboard
NoMethodError in Admin::DashboardController#index
undefined method `asideSection' for #<Admin::DashboardController:0x00007fc544017d70>
here is my application_conrtoller.rb
class ApplicationController < ActionController::Base
before_action :asideSection
def hhome
end
def getAsideSection
#asideSections = Page.all
end
end
how can i fix it please.
before_action :asideSection tries to call a method named asideSection.
This method does not exist.
However, you have defined a method named: getAsideSection. I presume that this is what you want to be called.
So, you could either change that to: before_action :getAsideSection, or rename the method to asideSection.
Here is how I would write it, also following the ruby style guide convention of using snake_case for variables and method names:
class ApplicationController < ActionController::Base
before_action :get_aside_sections
def home
# ...
end
private
def get_aside_sections
#aside_sections = Page.all
end
end

show content to first time visitor of rails app

I want a piece of content to display to first time visitors of a rails app, so I wrote a helper method that checks session and stores a cookie.
My controllers are set up like this:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
helper_method :first_time_visiting?
def first_time_visiting?
if session[:first_time].nil?
cookies.permanent[:first_time] = 1
end
end
end
class ItemsController < ApplicationController
before_action :first_time_visiting?
end
And then I'm calling the method in my view like this:
<% if first_time_visiting? %>
<div class="new-visitor-show">Test</div>
<% end %>
I should not be seeing "Test" after first visit, but I am. Am I using the helper method incorrectly?
You could use this (without helper):
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :first_time_visit, unless: -> { cookies[:first_visit] }
def first_time_visit
cookies.permanent[:first_visit] = 1
#first_visit = true
end
end
The function first_time_visit will be called only once, and so in the view :
<% if #first_visit %>
<div class="new-visitor-show">Test</div>
<% end %>
I think you should be checking the cookies instead session.
def first_time_visiting?
if cookies[:first_time].nil?
cookies.permanent[:first_time] = true
true
else
false
end
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?

Model Access throughout Entire Rails Application

Ruby 1.9.3 + Rails 3.2.8
I have a view that is rendered on every page in my app inside a partial:
<span id="sync-time">
<%= #sync.dropbox_last_sync.strftime('%b %e, %Y at %H:%M') %>
</span>
In order to use my syncs model and have access to the dropbox_last_sync method, I have to include it in every controller throughout my app. For example:
class EntriesController < ApplicationController
def index
#sync = current_user.sync
end
end
...
class CurrenciesController < ApplicationController
def index
#sync = current_user.sync
end
end
...etc.
Is there a way I can make the syncs model available everywhere by including it in my Application Controller somehow?
You should be able to add a before_filter in your application controller:
before_filter :setup_sync
def setup_sync
if current_user
#sync = current_user.sync
end
end
You need to be careful that your setup_sync filter runs after whatever code you are using to set up your current_user. This is probably another before_filter though so provided you have before_filter :setup_sync declared after your current user filter it will work fine.
This is better:
class ApplicationController < ActionController::Base
before_filter :authenciate_user!
before_filter :index
def index
#sync = current_user.sync
end
end
You're using current_user always, so you need to have before_filter :authenciate_user! here aswell and above the other one.

rails: how do i access a method in my application controller?

Noob scoping issue, I imagine. :\
class ApplicationController < ActionController::Base
protect_from_forgery
#locations = get_locations
def get_locations
Location.where(:active => true).order('name').all
end
end
Error:
undefined local variable or method `get_locations' for ApplicationController:Class
Two questions:
1) What's with the error? Am I calling the method incorrectly?
2) How do I access this method from a sub-classed controller?
You're calling get_locations within the class scope, but the method is an instance method, not a class method. If for example you used def self.get_locations then you would be providing a class method, one of which you can use within the class scope (after you have defined it, not before like you're doing).
The problem here is the logic, what is this method for? What do you intend to use #locations for? If it's to go inside your application view, then you should put this method into the ApplicationHelper module, and call it from inside the relevant action. If you'd like it in another view on another controller and you'd like to use #locations inside your locations method, perhaps your setup might look something like this:
PagesController
class PagesController < ActionController::Base
def locations
#locations = Location.where(:active => true).order('name').all
end
end
locations.html.erb
<% #locations.each do |location| %>
<%= # do something with 'location' %>
<% end %>
If you'd like to use this inside of your application.html.erb you can simplify it quite some..
ApplicationController
class ApplicationController < ActionController::Base
protect_from_forgery
def locations
Location.where(:active => true).order('name').all
end
end
application.html.erb
<% locations.each do |location| %>
<%= # do something with location %>
<% end %>
The answer boils down to logic, and to really figure out exactly what you're looking for, more details would probably be required.
You're calling it from the class scope, not from an instance scope. more likely what you want is the following:
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :setup_locations
private
def setup_locations
#locations = Location.where(:active => true).order('name').all
end
end
To make your original example work, you'd need to make #get_locations defined on self (which points to the class at definition), like so:
class ApplicationController < ActionController::Base
protect_from_forgery
#locations = get_locations
def self.get_locations
Location.where(:active => true).order('name').all
end
end
The problem with that code is that #locations will only be available from the class level as a class instance variable, which is comparable to a static variable in most other languages, and which probably isn't what you want.
I imagine that this line:
#locations = get_locations
... is trying to access the class level method get_locations and not the instance method.
The clue here is that the error message is showing that it can't find it on the class itself (ApplicationController:Class) and not an instance of that class. That means that you're in the class scope, not instance scope.
This would fix it:
def self.get_locations
Location.where(:active => true).order('name').all
end
Even the question is quite old, you can also call your controller action anywhere just by calling:
ApplicationController.new.get_locations

Resources