I have some 10,000+ records in my model. In active_admin index page for that model I have set config.paginate = false. So all the 10,000+ records are shown by default.
How can I limit the number to say last 500 records. I have tried using the below method described here, but its not doing anything to the index page.
ActiveAdmin.register Post do
controller do
def scoped_collection
Post.all.limit(500)
end
end
end
set custom # of rows on page with controller before_filter
controller do
before_filter :set_per_page_var, :only => [:index]
def set_per_page_var
session[:per_page]=params[:per_page]||30
#per_page = session[:per_page]
end
end
and render sidebar with corresponding text input (you can render it as a drop-list)
#...
sidebar('Rows on page', :only => :index) do
form do |f|
f.text_field nil, 'per_page', :value => session[:per_page]
end
end
The issue is this code in Active Admin:
module ActiveAdmin
class ResourceController < BaseController
module DataAccess
def per_page
return max_csv_records if request.format == 'text/csv'
return max_per_page if active_admin_config.paginate == false
#per_page || active_admin_config.per_page
end
def max_csv_records
10_000
end
def max_per_page
10_000
end
end
end
end
When the paginate config option is set to false, it defaults to the number value returned by max_per_page. If you're fine with overriding it globally, you can put this in an initializer:
# config/initializers/active_admin_data_access.rb
module ActiveAdmin
class ResourceController < BaseController
module DataAccess
def max_per_page
500 # was 10,000
end
end
end
end
I was looking for an answer to this same question. I was unable to limit the number of records, so instead I have opted for putting a default value in one of my filters that guarantees an empty page when it loads.
(NOTE: I stole this idea from this stackoverflow question here:: Set ActiveAdmin filter default value )
Example::
In this example, I set a filter called "my_filter_id" equal to "0" in the "before_filter" method if all of the parameters are blank.
ActiveAdmin.register MyModel do
before_filter my_filter_id: :index do
params[:q] = {my_filter_id_eq: 0} if params[:commit].blank?
end
end
Use
Post.limit(500) instead of Post.all.limit(500) so it will minimize the latency.
controller do
def scoped_collection
Post.limit(500)
end
end
index :pagination_total => false do
selectable_column
column :id
column :user_name
column :country
column :city
end
Hope this will help someone.
Try below code. Replace something with your model name.
result = Something.find(:all, :order => "id desc", :limit => 5)
while !result.empty?
puts result.pop
end
Related
I have a scope that uses RubyGeocoder method, near, to filter events by location using param[:searchCity]. The param gets the user's geolocation so it shows events only near them. I currently have it working in my events_controller index action, but I also need to call it on my home page.
Considering it's a filter that gets data from the database, I thought it would be best to go in the model, but I'm finding conflicting information on whether having a param in the model is ok or bad practice. Also, I can't get it to work in the model with the param present.
What's the best practice for something like this? Where should I place the scope, the model, controller, helper, or somewhere else?
Here's my code:
Model:
class Event < ActiveRecord::Base
# attr, validates, belongs_to etc here.
scope :is_near, self.near(params[:searchCity], 20, :units => :km, :order => :distance) #doesn't work with the param, works with a "string"
end
Controller:
def index
unless params[:searchCity].present?
params[:searchCity] = request.location.city
end
#events = Event.is_near
# below works in the controller, but I don't know how to call it on the home page
# #events = Event.near(params[:searchCity], 20, :units => :km, :order => :distance)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #events }
end
end
The line I'm calling in my home page that gets how many events are in the area
<%= events.is_near.size %>
Edit: Using a lambda seems to be working. Is there any reason I shouldn't do it this way?
Model:
class Event < ActiveRecord::Base
scope :is_near, lambda {|city| self.near(city, 20, :units => :km, :order => :distance)}
end
Controller:
def index
#events = Event.is_near(params[:searchCity])
...
home.html.erb
<%= events.is_near(params[:searchCity]).size %>
Accessing the params in model is not possible. Params is something which is made to exist only at controller and view level.
So best way is to write some helper method in controller to perform this.
Class Mycontroller < ApplicationController
before_action fetch_data, :only => [:index]
def fetch_data
#data = Model.find(params[:id])#use params to use fetch data from db
end
def index
end
Currently I have User model, which is registered in user.rb as a new resource for ActiveAdmin. Generated page displays all users with scopes (all/journalists/startup_employees). Now I want to create another page for the same resource, and the same scopes, but there should be only records with waiting field set to true (and the previous page should displays only this with :waiting => false). How could I do that? I know I could do that with filters, but I need two separate pages, with two links in menu.
// SOLUTION
It was even easier than advices (thanks guys!):
ActiveAdmin.register User, :as => 'Waitlist User' do
menu :label => "Waitlist"
controller do
def scoped_collection
User.where(:waitlist => true)
end
end
# code
scope :all
scope :journalists
scope :startup_employees
end
ActiveAdmin.register User do
controller do
def scoped_collection
User.where(:waitlist => false)
end
end
# code
scope :all
scope :journalists
scope :startup_employees
end
STI (Single table inheritance) can be used to create multiple "sub-resources" of the same table/parent model in Active admin
Add a "type" column in user table as a string
Add this to User model to mirror waiting field with type field
after_commit {|i| update_attribute(:type, waiting ? "UserWaiting" : "UserNotWaiting" )}
Create the new models UserWaiting and UserNotWaiting
class UserWaiting < User
end
class UserNotWaiting < User
end
Create Active Admin resources
ActiveAdmin.register UserWaiting do
# ....
end
ActiveAdmin.register UserNotWaiting do
# ....
end
You can run a first-time sync in console
User.all.each {|user| user.save}
..............
Another way could be to skip the type column (steps 1,2 and 5) and solve the rest with scopes.
Step 3 and 4 above
Then create the scopes
#model/user.rb
scope :waiting, where(:waiting => true)
scope :not_waiting, where(:waiting => false)
Scopes in Active Admin
#admin/user.rb
scope :waiting, :default => true
#admin/user_not_waitings.rb
scope :not_waiting, :default => true
Just make sure the other scopes in these two pages are also filtered on waiting/not_waiting
you could use a parameter to distinguish the cases and render different actions depending on the parameter:
link_to users_path(:kind => 'waiting')
and in the users_controller.rb
def index
if params[:kind]=='waiting'
#users= Users.where(:waiting => true)
render :action => 'waiting' and return
else
# do your other stuff
end
end
then put your new, different page (partial) in app/views/users/waiting.html.erb
If you want to use a different layout for this page add the layout parameter to render:
render :action => 'waiting', :layout => 'other_layout' and return
My Active admin version is 0.3.0, other than that m also using 'Will_paginate' i had made the configuration settings of conflict between kaminari and will_paginate but still m getting this error. i dont know where m making a mistake everything is working fine for other model but not for this model, need help, i have searched also found some links but not get satisfactory answer, it give me error on bold line
ActiveAdmin.register User do
menu :parent => 'Reports'
filter :id
filter :user_id
filter :updated_at
# and other filters
scope :all, :default => true do |user|
User.all
end
scope :active do |user|
User.where("user.status = ?", 'actvie')
end
scope :rejected do |user|
User.where("user.status = ?", 'non_active')
end
actions :index, :show
index do
column "ID" do |u|
link_to u.id, cs_user_path(u)
end
column "Status" do |u|
status_tag(u.status)
end
column "User" do |u|
link_to(u.user.full_name, cs_user_path(u.user)) rescue nil
end
end
collection_action :index, :method => :get do
scope = User.includes([:group,:address]).scoped
scope = scope.order params[:order].gsub(/_/,' ') if params[:order]
#collection = scope.paginate(:per_page => 25,:page => params[:page]) if params[:q].blank?
#search = scope.metasearch(clean_search_params(params[:q]))
**super do |format|**
format.html {
render "active_admin/resource/index"
}
end
end
end
The GitHub documentation of will_paginate states that arrays are not supported that well.
I will suggest using the kaminari gem which includes a helper method for array pagination.
You should be able to take it from here.
I've been drying up one of our controllers in our rails 2.3 app, and I've run up against a problem using an instance variable assigned in a helper_method. Originally, the situation was like this:
home_controller.rb:
class HomeController < ActionController::Base
def index
end
def popular
#popular_questions = PopularQuestion.paginate :page => params[:page],
<some complex query>
end
end
home_helper.rb:
module HomeHelper
def render_popular_questions
#popular_questions = PopularQuestion.paginate :page => 1,
<some complex query>
render :partial => 'popular'
end
end
home/index.html.haml
-cached do
.popular=render_popular_questions
home/popular.html.haml
=render :partial => 'popular'
home/_popular.html.haml
-if #popular_questions.length > 0
<show stuff>
hitting either / or /popular showed the appropriate box of popular questions.
Now, since the query was pretty much duplicated, and since paginate will use the correct page by default, I refactored this as:
home_controller.rb:
class HomeController < ActionController::Base
helper_method :get_popular_questions
def index
end
def popular
get_popular_questions
end
private
def get_popular_questions
#popular_questions = PopularQuestion.paginate :page => params[:page],
<some complex query>
end
end
home_helper.rb:
module HomeHelper
def render_popular_questions
get_popular_questions
render :partial => 'popular'
end
end
now when I go to /, I get
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.length
being raised in line 1 of home/_popular.html.haml
It seems that variables set from within helper_methods called from within helpers aren't accessible to the template. Have I made a mistake somewhere? If not, how do I use an instance variable assigned in a helper_method from a helper?
Pass them as parameters and local-variables:
home_controller.rb:
class HomeController < ActionController::Base
helper_method :get_popular_questions
def index
end
def popular
#popular_questions = get_popular_questions
end
private
def get_popular_questions
# remember that the final statement of a method is also the return-value
PopularQuestion.paginate :page => params[:page],
<some complex query>
end
end
home_helper.rb:
module HomeHelper
def render_popular_questions
questions = get_popular_questions
render :partial => 'popular', :locals => {:questions => questions}
end
end
now in your partial, use "questions" instead of "#popular_questions"
Just make sure that the main template for "popular" also need to populate this local variable too.
I have the following (heavily simplified) model, that uses will_paginate
class Search < ActiveRecord::Base
attr_reader :articles
def after_initialize
#articles = Article.paginate_by_name name, :page => 1
end
end
and the controller code in my show action is
#search = Search.new(params[:search])
This all works fine, but notice i hard coded the page number to 1, problem is passing params[:page] value into the after_initialize method, can anyone suggest an elegant way to do this please?
Thanks
Add a page parameter (or even better an options hash parameter) to the initialize method:
class Search
def initialize(search, options = {})
#options = options
end
def after_initialize
#articles = Article.paginate_by_name name, :page => #options[:page]
end
end
and then in your controller:
#search = Search.new(params[:search], :page => params[:page])
You can even supply default values to the option hash, if you like.