How to specify conditions in each function in Rails.
#page = 1
#allRecords = #This result will come from API.. It have 500 records.
resultArray = []
#allRecords.each do |t| #need to specify condition here based on #page value
#processes...
resultArray << t
end
render :json => resultArray
i will send #page number to controller. Then resultArray will sent final values
Input : #page = 1
Output : resultArray = Records 1 - 50
Input : #page = 2
Output : resultArray = Records 51 - 100
Input : #page = 3
Output : resultArray = Records 101 - 150
like wise...
How can i achieve this.
Any help would be appreciated. Thanks.
#page = 1
#allRecords = #This result will come from API.. It have 500 records.
per_page = 50
resultArray = #allRecords.slice(#page + (#page - 1) * per_page, per_page)
# if result is not Array (Enumerable)
#resultArray = #allRecords.to_a.slice(#page + (#page - 1) * per_page, per_page)
Related
I am working on a kind of order where I have multiple amount in different currencies in just one attribute. So am trying to make sum on different currencies inside that attribute using other attributes in the table, which works fine but outputs the result as a count of all the rows instead of just showing the sum of the random values calculated.
orders_controller.rb
module Admin
module Statistic
class OrdersController < BaseController
def show
#orders_grid = ::Statistic::OrdersGrid.new(params[:statistic_orders_grid]) do |value|
value.page(params[:page]).per(20)
end
#assets = #orders_grid.assets
##fee_groups = {:fee => #assets.sum(:fee)}
#fee_groups = {
:fee => #assets.sum{|t|
olaoa = t.type
market_string = t.currency
base_currency = market_string.slice(0..2)
quote_currency = market_string.slice(3..5)
if olaoa == 'OrderBid' and base_currency == 'btc'
"#{ t.fee.to_s + ' ' + base_currency.upcase }"
elsif olaoa == 'OrderAsk' and quote_currency == 'ngn'
"#{ t.fee.to_s + ' ' + quote_currency.upcase }"
end
}
}
#orders_filter = true
#orders_group = true
end
end
end
end
summary.htm.slim
.panel.panel-default
.panel-heading
h4.panel-title.row
a data-parent="#filter-accordion" data-toggle="collapse" href="#summary"
span.col-xs-8.text-muted = t('admin.statistic.summary')
span.col-xs-4.text-right.text-muted = t('admin.statistic.click-to-expand')
#summary.panel-collapse.collapse
.panel-body
.datagrid-groups
- if !#orders_group
- if groups
- groups.each do |key, val|
.datagrid.group.row
span.col-xs-2.title = t("admin.statistic.#{controller_name}.#{controller.action_name}.#{key}")
span.col-xs-10.value = val
- if #orders_group
/ Summary Count Loop
- if groups
- groups.each do |key, val|
.datagrid.group.row
span.col-xs-2.title = t("admin.statistic.#{controller_name}.#{controller.action_name}.#{key}")
span.col-xs-10.value = pluralize(val, 'Order')
/ Summary Fees Loop. This is the Fee loop causing problem if am rigth and I dont know how to fix this.
- if #fee_groups
- #fee_groups.each do |key, val|
.datagrid.group.row
span.col-xs-2.title = t("admin.statistic.#{controller_name}.#{controller.action_name}.#{key}")
span.col-xs-10.value = val
The result of the code
So as you can see it renders 0.0BTC 5 times because the filter only has 5 orders. How do i deal with this. I want just the sum of all BTCs to show in the result instead of showing it 5 times.
Any help will be appreciated.
Because you sum strings in you're #fee_groups query that will results in putting strings next to each other instead of a total amount.
If you call it like this
#fee_groups = { fee: #assets.sum{|t| t.fee}}
You will get the total sum of you're assets.
Let's say i have two relation arrays of a user's daily buy and sell.
how do i iterate through both of them using .each and still let the the longer array run independently once the shorter one is exhaused. Below i want to find the ratio of someone's daily buys and sells. But can't get the ratio because it's always 1 as i'm iterating through the longer array once for each item of the shorter array.
users = User.all
ratios = Hash.new
users.each do |user|
if user.buys.count > 0 && user.sells.count > 0
ratios[user.name] = Hash.new
buy_array = []
sell_array = []
date = ""
daily_buy = user.buys.group_by(&:created_at)
daily_sell = user.sells.group_by(&:created_at)
daily_buy.each do |buy|
daily_sell.each do |sell|
if buy[0].to_date == sell[0].to_date
date = buy[0].to_date
buy_array << buy[1]
sell_array << sell[1]
end
end
end
ratio_hash[user.name][date] = (buy_array.length.round(2)/sell_array.length)
end
end
Thanks!
You could concat both arrays and get rid of duplicated elements by doing:
(a_array + b_array).uniq.each do |num|
# code goes here
end
Uniq method API
daily_buy = user.buys.group_by(&:created_at)
daily_sell = user.sells.group_by(&:created_at
buys_and_sells = daily_buy + daily_sell
totals = buys_and_sells.inject({}) do |hsh, transaction|
hsh['buys'] ||= 0;
hsh['sells'] ||= 0;
hsh['buys'] += 1 if transaction.is_a?(Buy)
hsh['sells'] += 1 if transaction.is_a?(Sell)
hsh
end
hsh['buys']/hsh['sells']
I think the above might do it...rather than collecting each thing in to separate arrays, concat them together, then run through each item in the combined array, increasing the count in the appropriate key of the hash returned by the inject.
In this case you can't loop them with each use for loop
this code will give you a hint
ar = [1,2,3,4,5]
br = [1,2,3]
array_l = (ar.length > br.length) ? ar.length : br.length
for i in 0..array_l
if ar[i] and br[i]
puts ar[i].to_s + " " + br[i].to_s
elsif ar[i]
puts ar[i].to_s
elsif br[i]
puts br[i].to_s
end
end
I have this:
source = MyModel.all.some_filter(some_condition).order("condition123 ASC") # 1
res1 = source.page(params[:page]).per(PAGE_SIZE) # 2
I also want to retrieve 2 more items from source that "surround" res1 - its neighbors :
neighbour1 =
if params[:page] > 1
source.page(params[:page] - 1).per(1).order("condition123 DESC")
else
nil
end
neighbour2 =
unless last_page(source)
source.page(params[:page] + 1).per(1)
else
nil
end
and merge the results all together:
full_result = neighbour1 + res1 + neighbour2
First off all, is there any way to make it more effective?
And how do I merge the results if neighbour1 or neighbour2 are nil? If do this:
if params[:page] > 1
source += source.page(params[:page] - 1).per(1).order("condition123 DESC")
end
then source will be converted to Array and I won't be able to use page anymore. I know I could do this via Kaminary.page but I prefer just to get source not to convert itself to array and remain MyModel::ActiveRecord_Relation
I have two models (Folder and Document) which I need to show in a single view together. However, to reduce the number of queries sent I am collecting the Documents only if the folders are less than 12 (my :per_page). While this is working fine, I am stuck in a particular case,
When my total documents are less than 12 and folders are less than 12 but together are more than 12, the pagination fails.
Below is the code to calculate which page to be shown where f_page returns the page for the Folder pagination and d_page returns the page number for the document collection.
def f_page(page_cnt, size)
page_cnt.present? and size.nonzero? ? page_cnt.to_i <= (size/12 + (size%12==0 ? 0 : 1)) ? page_cnt.to_i : (size / 12 ) + (size%12==0 ? 0 : 1) : 1
end
def d_page(page_cnt, fc, dc)
page_cnt = page_cnt.present? ? page_cnt : 1
puts page_cnt
dpg = 1
if (fc/12+1 == page_cnt.to_i)
dpg = 1
elsif ((fc/12+1) < page_cnt.to_i)
if (fc < 12)
unless (dc <= 12)
dpg = page_cnt
else
dpg = 1
end
else
(fc/12 == 0) ? (dpg = page_cnt.to_i - (fc/12+1)) : (dpg = page_cnt.to_i - (fc/12))
end
end
puts "dpg = #{dpg}"
return dpg
end
Both are together collected and paginated which is shown in the view.
f = Folder.action_folder_collection(#action, current_user).paginate(:page => params[:page], :per_page => 12)
if (f.count < 12)
d = Document.action_document_collection(#action, current_user).paginate(:page => d_page(params[:page], total_folders, total_documents), :per_page => per_page-f.count)
end
collection << f
collection << d
#collection = collection.flatten.paginate(:page => 1,:per_page => 12,:total_entries => total)
How do I solve it?
I have just solved the similar problem. My paginate_catalog_children helper receives either an AR collection or an array of collections as a parameter and returns WillPaginate::Collection object containing elements from all collections.
def paginate_catalog_children catalog_children, page
per_page = 20
if catalog_children.is_a? ActiveRecord::Relation
catalog_children.paginate(:per_page => per_page, :page => page)
else
# paginating array of collections
WillPaginate::Collection.create(page, per_page) do |pager|
catalog_children_counts = catalog_children.map(&:count)
result = []
offset = pager.offset
items_left = pager.per_page
catalog_children.each_with_index do |collection, index|
break if items_left == 0
if catalog_children_counts[index] <= offset
# skip this collection
offset -= catalog_children_counts[index]
else
collection_items = collection.limit(items_left).offset(offset)
result += collection_items
items_left -= collection_items.size
offset = 0
end
end
pager.replace(result)
pager.total_entries = catalog_children_counts.sum
result
end
end
end
What I want to do is something like this:
searchid = 4
while searchid != -1
#a += A.find(searchid)
#b = B.find(searchid)
searchid = #b.parentid
end
The problem being the line
#a += A.find(searchid)
The error being something like
NoMethodError: undefined method `+' for #<A:0x173f9a0>
So, how do you combine multiple 'find' requests?
You have to initialize #a = [] as an array before the += .
searchid = 4
#a = []
while searchid != -1
#a += A.find(searchid)
#b = B.find(searchid)
searchid = #b.parentid
end
You can combine them like:
searchid = 4
#a = []
while searchid != -1
#a += A.find(searchid)
#a += B.find(searchid)
searchid = #a.last.parentid
end
Got it to work (with help).
Did the following:
#a = []
with
#a << A.find_by_something(something)
seems to have worked.
Also using #a.compact! to get rid of the null entries.
Thanks for all the help :)