I am trying to create a dynamic menu with simple navigation.
The problem is that the menu only works on the show action that should show dynamic menu items. All other pages gives the error:
undefined method `model_name' for #<Class:0x9236118>
I have read this, but have not found any solution:
https://github.com/andi/simple-navigation/wiki/Dynamic-Navigation-Items
My navigation.rb:
sub_nav.item :virk, 'Virksomheder', virk_path, :link => {:style => 'font-weight:bolder;', :class => 'submini'} do |virknavn|
virknavn.item :virksom, #virksomhed.try(:name), url_for(#virksomhed), :highlights_on => /virksomheder\/[0-9]+/
end
I only want the virknavn menu items to be highlighted on:
/virksomheder/:some virksomhed name
My virksomhed controller:
def index
#virksomheds = Virksomhed.all
render :layout => 'page'
end
# GET /webhosts/1
# GET /webhosts/1.xml
def show
#virksomhed = Virksomhed.find(params[:id])
render :layout => 'page'
end
I did manage to figure out that I just could set a if statement in the navigation.rb:
if params[:id].blank?
params[:id] = Virksomhed.first.id
end
#virksomhed = Virksomhed.find(params[:id])
if #virksomhed.blank?
#virksomhed = Virksomhed.first
end
And it did the magick.
Related
I'm using the Twilio API in a rails app to show a user a list of their recordings. Say a user has 11 recordings total, and I'm showing them 3 per page.
twilio_controller.rb
def calls
#user = current_user
#account_sid = #user.twilio_account_sid
#auth_token = #user.twilio_auth_token
#page_size = 3
#page = params[:page_id] || 0
#sub_account_client = Twilio::REST::Client.new(#account_sid, #auth_token)
#subaccount = #sub_account_client.account
#recordings = #subaccount.recordings
#recordingslist = #recordings.list({:page_size => #page_size, :page => #page})
end
calls.html.erb
<% #recordingslist.each do |recording| %>
<tr>
<td><%= recording.sid %></td>
</tr>
<% end %>
<%= link_to "Next Page", twilio_calls_path(#page + 1) %>
routes.rb
#twilio routes
post 'twilio/callhandler'
get 'twilio/calls'
match 'twilio/calls' => 'twilio#page', :as => :twilio_page # Allow `recordings/page` to return the first page of results
match 'twilio/calls/:page_id' => 'twilio#page', :as => :twilio_page
Paging info is built into the Twilio response such that
#recordingslist.next_page
gives me the next 3 recordings (verified in rails console). How do I link to that so that when a user clicks the link, the table loads the next 3 results?
Thanks!
You can use a gem like Kaminari for Pagination.
https://github.com/amatsuda/kaminari
I would recommend utilizing the paging functionality that ships with twilio-ruby. According to the docs:
ListResource.list() accepts paging arguments.
Start by create a route for your Twilio list view. Make sure you can pass a page_id parameter – this is how your controller action will know which page to render:
# config/routes.rb
match 'recordings/page/:page_id' => 'twilio#page', :as => :twilio_page
match 'recordings/page' => 'twilio#page', :as => :twilio_page # Allow `recordings/page` to return the first page of results
Then, in the page action, pull the page_id parameter (or set if to 1 if there is no page_id, and pass the page_number and page_size as arguments to #recordings.list:
# app/controllers/twilio_controller.rb
def page
page_size = 3
#page = params[:page_id] || 1
#sub_account_client = Twilio::REST::Client.new(#account_sid, #auth_token)
#subaccount = #sub_account_client.account
#recordings = #subaccount.recordings
#recordingslist = #recordings.list({:page_size => page_size, :page => page)})
end
Finally, in your view, pass the page number to twilio_page_path in your link_helper – just make sure to adjust the page number accordingly (+1 for the next page, -1 for the previous page:
# view
<%= link_to "Next Page", twilio_page_path(#page.to_i + 1) %>
<%= link_to "Previous Page", twilio_page_path(#page.to_i - 1) %>
Note that – if you're at the start or end of your list – you may inadvertently end up passing an invalid page_id. Therefore, you may want to implement some exception handling in your page controller action:
# app/controllers/twilio_controller.rb
def page
begin
#page = params[:page_id] || 1 # If `page_id` is valid
rescue Exception => e
#page = 1 # If `page_id` is invalid
end
# Remaining logic...
end
I have built a 'NewsItem' controller that contains a method called 'top'. This is called by a javascript request to update a DIV on the page every 10 seconds. This is all working well.
def top(number = false)
# set the default value to use for the number
default_number = 10;
# perform checks on the variable
if number == false
if params.include?(:number)
number = params[:number]
else
number = default_number
end
end
# Run query to get the required news items
items = NewsItem.all( :order => ("created_at DESC"),
:include => [:profile],
:limit => number)
# iterate around the items that have been returned
#top_news = ""
items.each do |item|
#top_news += render_to_string :partial => "partials/news_item", :locals => {:item => item}
end
respond_to do |format|
format.html { render :partial => "partials/news_top"}
end
end
This is called with '/news/top' or '/news/top/20' to change the number of items that are returned.
The problem is that when the page is first loaded the 'news' DIV is empty for 10 seconds, until the JavaScript runs to update the DIV. So I want to ensure that the DIV is already populated by calling this function.
Now as I want the 'news' DIV to be available in all pages it is defined in the 'layouts/application.html.erb' template. So I need to call the 'top' method in the 'NewsItem' controller so that it can be rendered into the initial HTML. This is where I am struggling as I cannot work out how to use the 'helper_method' to make this available at this stage.
I have a feeling that I am missing something here and not understanding the whole process.
Thanks very much for any assistance.
Regards, Russell
Try separating out the logic. Maybe you make a method called top_news that returns the value you use in top_news. And since you're passing back a partial, use it to build the string. Partials are meant to be used to iterate over a list.
def index
#top_news = top_news
end
def top
#top_news = top_news
respond_to do |format|
format.html { render :partial => "partials/news_top"}
end
end
private
def top_news(number = false)
# set the default value to use for the number
default_number = 10;
# perform checks on the variable
if number == false
if params.include?(:number)
number = params[:number]
else
number = default_number
end
end
# Run query to get the required news items
items = NewsItem.all( :order => ("created_at DESC"),
:include => [:profile],
:limit => number)
# iterate around the items that have been returned
return render_to_string :partial => "partials/news_item", :collection => items, :as => :item
end
The other solution you can follow is to not render any partials in the controller at all except for your one javascript method and instead make a method in your model to do exactly what you're doing here.
class NewsItem
def top_news(number=20) # pass in number with default 20
NewsItem.where( :order => ("created_at DESC"),
:include => [:profile],
:limit => number)
end
end
Then just call it from your controllers to get that so you can use it in your views and iterate over it using partials in your views.
I'm new to Activeadmin and rails and I need some help.
I have a model that is paginated and I want to allow the user to change the pagination value or disable it completely, so it can print (to a printer) all the records (or filtered ones) for instance.
I know I can set the pagination using #per_page in :before_filter, but I can't figure out how I can change this value during execution.
To solve the problem of needing to show all the unpaginated records I defined a custom page, but in this page the filter or scope don't work so it's kind of useless.
How can I create a Print button in Active Admin?
This is a workaround to do it, I know it is not the best solution but it works ! :)
This is the app/admin/mymodel.rb file
ActiveAdmin.register MyModel do
before_filter :paginate
#other code
controller do
def paginate
#per_page = params[:pagination] unless params[:pagination].blank?
end
end
index do
panel "Pagination" do
render partial: "paginate", locals: {resource: "mymodels"}
end
#other code
end
#other code
end
And for the app/views/admin/articles/paginate.html.haml
#pagination_form
= form_tag do
= label_tag :pagination, "Number of " + resource + " per page : "
= text_field_tag :pagination
= submit_tag "Filter"
:javascript
$("#pagination_form form").submit(function(e){
e.preventDefault();
window.location = "/admin/#{resource}?pagination=" + $("#pagination").val();
})
Hoping that my answer can people with the same problem :)
I found a solution and I'm answering my own question for someone who has the same problem.
It may not be the best solution but it works, if someone has a better way please share:
ActiveAdmin.register mymodel do
before_filter :apply_pagination
# other code
index :download_links => false, :as => :table, :default => true do
if params[:pag].blank?
div link_to(I18n.t("text_for_the_link"), 'mymodel?pag=1', :class => "class_for_link")
else
div link_to(I18n.t("print.print"), 'mymodel', :class => "class_for_link")
end
# other code
end
controller do
def apply_pagination
if params[:pag].blank?
#per_page = 50
else
#per_page = 99999999
end
# other code
end
end
I found out you can define this by registering the following line on the resource:
ActiveAdmin.register MyModel do
config.per_page = [20, 50, 100, 200]
end
It automatically adds a select box in the index pagination with the preset values given in the array.
I have a map which has got marker based on state of US. Each state has n number of city.
I have got a state model, controller and city model, controller.
When I click on the marker of the state, I want the list of cities to be displayed in the info window.
All this information is appearing on the homepage.
This is what I have done so far :-
home_controller.rb
def index
#states = State.all.to_gmaps4rails do |state,marker|
marker.infowindow render_to_string(:partial => "/states/gmaps4rails_infowindow", :locals => {:object => state})
marker.json({:id => state.id})
end
end
home/index.html.haml
=gmaps({"map_options" =>{ "auto_zoom" => false, "zoom" => 3}, "markers" => { "data" => #states } })
state_controller.rb
def gmaps4rails_infowindow
#state = Gmaps.map.markers
end
states/_gmaps4rails_infowindow.html.haml
=#state.cities.each do |city|
=city.name
Needless to say that it is not working. Can someone please help me out?
Well, your home_controller.rb is fine. you write here you want to use a partial with a local variable named object.
In the partial itself, you write:
=#state.cities.each do |city|
=city.name
The instance variable isn't defined there, you defined a local variable just above.
Replace with:
=object.cities.each do |city|
=city.name
From there it should work.
Notice:
def gmaps4rails_infowindow
#state = Gmaps.map.markers
end
is:
useless: you define the infowindow in the controller
wrong: Gmaps.map.markers only lives as js variable
I am aware this is a very basic question, we are very new to rails and have been unable to find a specific answer to this question.
Background: We have just 1 database containing product information (called Product), one column (type) contains information regarding the product type and is either a value of 1 or 2.
Aim: create 3 buttons on a page which correspond to different user choices
e.g. Button 1 - show items of type 1; Button 2 - show items of type 2; Button 3 - show all items.
Ideally the information regarding the button pressed should be visible to a number of pages within a class (we have an index page, as well as 3 others in the controller)
Would somebody be able to provide an outline of the code required to do this please?
I am guessing it is some combination involving the ..._controller.rb and..._helper.rb?
Thanks a lot for your patience
What I would do is the following.
First, create a scope or named_scope in your Project model for finding projects by type. You'll then be able to use this scope to query your projects depending on type.
# Rails 3
class Project
scope :by_type, lambda{ |type| where(type: type.to_i) unless type.nil? }
end
#Rails 2
class Project
named_scope :by_type, lambda do |type|
{ :conditions => { :type => type.to_i } } unless type.nil?
end
end
Next, create a before filter in your controller to load the projects of that type. The before filter should be applied to all pages where you want the buttons to be present:
class ProjectsController
before_filter :load_projects, :only => [:index, :action1, :action2]
protected
def load_projects
#projects = Project.by_type(params[:type])
end
end
Finally, create a partial for the buttons that you can include in the views that have the option of displaying different project types:
# _project_options.html.erb
<%= link_to "Button 1", :controller => params[:controller], :action => params[:action], :type => '1' %>
<%= link_to "Button 2", :controller => params[:controller], :action => params[:action], :type => '2' %>
<%= link_to "Button 3", :controller => params[:controller], :action => params[:action], :type => '' %>
You can then include this partial in each of your related views. And you'll be able to display the projects by doing something like this (if you have an _projects.html.erb partial defined):
render #projects
You can load all the Products and then hide them selectively with some javascript. Just add a class to your markup for each type of product, like this:
<%= link_to #product.name, product_path(#product), :class => #product.type %>