alphabetically paginate users in rails - ruby-on-rails

I am trying to create an alphabetical pagination for rails. I have found some plugins and gems but they come up with errors so I am trying to create a custom pagination which isn't working quite right...WHy is this?
model(userrrrrr.rb)
def self.find_by_group
('A'..'Z').map do |letter|
#users = User.find_by_sql(:all, :conditions=>['LOWER(name) LIKE?', "#{letter.downcase}%"],:order=>'name ASC')
end
#users
end
User helper
def alphabetically_paginate(collection)
available_letters = User.find_by_group
content_tag(:ul, safe(alphabetical_links_to(available_letters)),
:class => "pagination")
end
def safe(content)
if content.respond_to?(:html_safe)
return content.html_safe
end
content
end
def alphabetical_links_to(available_letters)
available_letters = ('A'..'Z').to_a
('A'..'Z').map do |letter|
content_tag(:li, paginated_letter(available_letters, letter))
end.join(" ")
end
def paginated_letter(available_letters, letter)
if available_letters.include?(letter)
link_to(letter, "#{request.path}?letter=#{letter}")
else
letter
end
end
end
views
-('A'..'Z').each do |char|
-if char == user.name[0]
= link_to :action => 'char'
=alphabetically_paginate(#users)
the views is incomplete as I am not sure how to proceed at the moment... I am thinkking about refreshing the page and display the list with only the A or B etc like a seaarch page

This is a bit late to the party, but it might help other users. I've created a gem that allows for alphabetical pagination using SQL queries here: https://github.com/lingz/alphabetical_paginate
It's as simple as:
Controller
def index
#users, #alphaParams = User.all.alpha_paginate(params[:letter], {db_mode: true, db_field: "name"})
end
View
<%= alphabetical_paginate #alphaParams %>
Hope it helps.

Related

Rails Call A Method Lastly In Action

I have something like that in my controller:
def index
#votes = Vote.all
end
private
def search
#votes = OtherVotes.all
end
I want to use search method in index action but I don't want to remove my #votes variable from index. If I use before_action, it calls method before the action so #votes doesn't change. Is it possible to call search method after my votes variable or ignore the variable without removing.
I normally go with this method when I'm looking to build a simple search:
http://railscasts.com/episodes/37-simple-search-form
Create a method in your vote.rb file:
class Vote
def self.search(search)
if search
self.where(:all, conditions: ['name LIKE ?', "%#{search}%"])
else
self.where(:all)
end
end
end
This means when you do Vote.search('term'), you'll bring up any records with a similair name. Replace name for whatever term you're searching for (i.e. title or category).
If there is no search term entered this method simply returns every instance. This means you can leave your controller looking like this:
def index
#votes = Vote.search(params[:search])
end
Finally the view for this would be something like:
<% form_tag votes_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
This will send a get request to the votes_path (the index action on your controller), with the search term parameter. If one is entered the search will return the relevant instances, and if not it will return all.
Try
class TempController < ApplicationController
after_action :search
def index
#votes = Vote.all
end
private
def search
#votes = OtherVotes.all
end
end

Importing an Excel file into Rails - Accessing the correct method in the Controller

I'm using Roo to import data from an Excel spreadsheet into my database. I think I've got the code in the controller down, but now I have no idea how to access this method to get it going. There are no errors -- it simply isn't doing anything as far as I can tell. Here's what I've tried.
Controller code
class ApplicantsController < ApplicationController
before_action :signed_in_user, only: [:index, :edit, :update]
def index
#applicants = Applicant.paginate(page: params[:page])
end
helper_method :fetch_excel_data
def fetch_excel_data
ex = Roo::Excelx.new("data.xlsx")
ex.default_sheet = ex.sheets.first
2.upto(6) do |line|
first_name = ex.cell(line, 'B')
last_name = ex.cell(line, 'C')
#imported_applicant = Applicant.new(first_name: first_name,
last_name: last_name)
end
end
end
Here I'm trying to access it by calling it from the index view.
index.html.erb
<% provide(:title, 'All applicants') %>
<h1>All applicants</h1>
<%fetch_excel_data%>
<%= will_paginate %>
<ul class="users">
<%= render #applicants %>
</ul>
<%= will_paginate %>
I know something here isn't clicking, but I can't figure out what.
You should call fetch_excel_data from your index action before you are querying the applications. Also, you are not saving the new records, Application.new needs to be replaced with Application.create for example
before_filter :fetch_excel_data
def index
#applicants = Applicant.paginate(page: params[:page])
end
private
def fetch_excel_data
ex = Roo::Excelx.new("data.xlsx")
ex.default_sheet = ex.sheets.first
2.upto(6) do |line|
first_name = ex.cell(line, 'B')
last_name = ex.cell(line, 'C')
Applicant.create(first_name: first_name,
last_name: last_name)
end
end
Since you are saving the imported records into the DB, the import part could be moved out into a rake task or into a separate controller / action so you could easily rerun. It does not need to be run each time you visit the page, I assume.

Ruby on Rails: How to redirect page based on post params in search_field?

I'm working on a little stock market app where the users can lookup company stock info based on the ticker symbol. After the user has posted the :symbol param in the search field, they should be redirected to the appropriate "company" page (like Wall Street Journal, Yahoo Finance, Google Finance, etc). I'm currently able to manually type in the route with the symbol and everything works good. For example, localhost:9292/company/GOOG. I'm a total noob, so any help would be greatly appreciated. Thanks!
I currently have this in my view:
<%== search_field_tag(:symbol, "Enter symbol") %>
<%== submit_tag ("Search") %>
This is in my routes:
get "/company/:symbol" => "main#company"
post "/company/:symbol" => "main#company_post"
EDIT: I'm using the MarketBeat gem to pull in the data, but I also have a Company table where I have columns symbol and name. Here is my controller:
class MainController < ApplicationController
def index
render :index and return
end
def company
#name = MarketBeat.company params["symbol"]
#symbol = MarketBeat.symbol params["symbol"]
#price = MarketBeat.last_trade_real_time params["symbol"]
#change = MarketBeat.change_and_percent_change params["symbol"]
#volume = MarketBeat.volume params["symbol"]
#days_range = MarketBeat.days_range params["symbol"]
#eps = MarketBeat.earnings_to_share params["symbol"]
#pe = MarketBeat.pe_ratio params["symbol"]
#stock_exchange = MarketBeat.stock_exchange params["symbol"]
market_cap = MarketBeat.market_capitalization params["symbol"]
# #market_cap is rounded to billions
#market_cap = market_cap.to_i / 1000
render :company and return
end
In your main#company_post method, put the following:
redirect_to "/company/#{params[:symbol]}"
So the routes should be:
get "/company/:symbol" => "main#company"
post "/company" => "main#company_post"
The controller:
def company_post
redirect_to "/company/#{params[:symbol]}"
end
The view:
<%= form_tag("/company", method: :post) do %>
<%= search_field_tag(:symbol, "Enter symbol") %>
<%= submit_tag ("Search") %>
<% end %>
At the end of your #company controller method you probably will do something like this
render "#{params[:symbol]}"
or
render partial: "#{params[:symbol]}"
along with have a template file with the same name of the company, like google.html.erb
Give it a try!
I make simple search system that looks almost like your task
Full example
routes.rb
post 'search' => 'vids#prepare_search', as: :prepare_search_vids
get 'search(/*query)' => 'vids#search', as: :search_vids
vids_controller.rb
# GET /search(/*query)
def search
#results = Title.search params[:query] if search_query?
if #results.count == 1
flash[:notice] = I18n.t 'vids.search.signle_result'
redirect_to #results[0].vid
end
#query = params[:query]
end
# POST /search
def prepare_search
query = params[:q] ? params[:q] : ''
redirect_to search_vids_path(query)
end
private
def search_query?
params[:query] and !params[:query].blank?
end
Also in your situation I recommend use asteriks instead of colon in routes http://guides.rubyonrails.org/routing.html#route-globbing-and-wildcard-segments

Rails generalizing a method that uses models

I am trying to generalize few methods that will be used by multiple models/views/controllers but i'm having no luck. Here is the original code that works when it is just for 1 set called Trucks.
View
<h2>Trucks</h2>
<%= form_tag trucks_path, :method => 'get' do %>
<%= hidden_field_tag :direction, params[:direction] %>
<%= hidden_field_tag :sort, params[:sort] %>
<p>
Search:
<%= text_field_tag :search %>
by
<%= select_tag :search_column, options_for_select(Truck.translated_searchable_columns(['attribute1']), params[:search_column]) %>
<%= submit_tag "Search" %>
</p>
<% end %>
<!-- Display code goes here, but im not showing since its just a table -->
Controller
def index
#trucks = Truck.search(params[:search], params[:search_column]).order(sort_column(Truck, "truck_no") + " " + sort_direction)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #trucks }
end
end
Model
class Truck < ActiveRecord::Base
attr_accessible :attribute1, :attribute2, :attribute3
def self.search(keyword, column_name)
if self.column_names.include?(column_name.to_s)
where("trucks.#{column_name} LIKE ?", "%#{keyword}%")
else
scoped
end
end
def self.searchable_columns(unwanted_columns)
self.column_names.reject{ |column| unwanted_columns.include?(column) }
end
def self.translated_searchable_columns(unwanted_columns)
columns = self.searchable_columns(unwanted_columns)
result = columns.map{ |column| [Truck.human_attribute_name(column.to_sym), column] }
result
end
end
All this works without a hitch, now I can't figure out for the life of me how to move these methods to lib and have them generalized so that lets say Trailers is able to call in the same method and pass in its information and achieve the same result. I am trying to make this code DRY as possible. Could anyone explain me what I need to do to achieve this? How does lib access the database?
The concept you're looking for is called a "concern". Rails has a convenience module for implementing concerns called ActiveSupport::Concern. Here's how you might extract your model methods:
module Searchable
extend ActiveSupport::Concern
module ClassMethods
def search(keyword, column_name)
if column_names.include?(column_name.to_s)
where("#{table_name}.#{column_name} LIKE ?", "%#{keyword}%")
else
scoped
end
end
def searchable_columns(unwanted_columns)
column_names.reject{ |column| unwanted_columns.include?(column) }
end
def translated_searchable_columns(unwanted_columns)
columns = searchable_columns(unwanted_columns)
columns.map{ |column| [human_attribute_name(column.to_sym), column] }
end
end
end
And then in your model:
class Truck < ActiveRecord::Base
include Searchable
attr_accessible :attribute1, :attribute2, :attribute3
end
As for where exactly you should store the Searchable module, it's up to you -- it just has to be someplace that's included in config.autoload_paths, just like a model or controller. Rails 4 introduced a convention that model concerns are stored in app/models/concerns, and controller concerns in app/controllers/concerns, but there is nothing special about these locations other than being autoloaded by default.

Simple search on a Globalize3 table in Rails

I am looking to implement a simple search function while using the globalize3 gem for Ruby on Rails. Since the translations of the model are stored in a separate table, the code below doesn't work as there is no longer a :name field in the products table. How can I adjust the code below to make the search function correctly?
products_controller.rb
#products = Product.search(params[:search]).all
index.html.erb
<%= form_tag products_path, method: :get do %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", name: nil %>
<% end %>
model
class Product < ActiveRecord::Base
translates :name
attr_accessible :name, :price, :released_at
def self.search(search)
if search
where('name LIKE ?', "%#{search}%")
else
scoped
end
end
end
You're in luck, I tackled exactly the same problem recently!
Luckly for you the answer is quite simple. You can use the class method with_translations to include translations for a given set of locales.
Here's the code:
def with_translations(*locales)
locales = translated_locales if locales.empty?
includes(:translations).with_locales(locales).with_required_attributes
end
Include it in your search method:
def self.search(search)
if search
with_translations.where('name LIKE ?', "%#{search}%")
else
with_translations
end
end
That should do it.
As an added note: you could add an optional locales parameter to the search method and pass it to with_translations to optionally narrow the search to terms in a particular language, say for example in the current locale.
Solved ...
def index
if params[:search]
#at = []
#at = Array.new
Article.translation_class.where("title LIKE ? OR description LIKE ?","%#{params[:search]}%","%#{params[:search]}%").all.each do |t|
#at.push t.article_id
end
#articles = Article.where(id: #at).recent_first.paginate(page: params[:page], per_page: 5)
else
#articles = Article.all.recent_first.paginate(page: params[:page], per_page: 5)
end
end

Resources