download leaderboard reports into a csv rails - ruby-on-rails

I have a reports controller where I have leaderboard. I would like to download the leader board into a csv file
here is the leaderboard code
def leaderboard
if params.has_key?(:start_date) && params.has_key?(:end_date) && params.has_key?(:account)
if params[:unit] == 'all'
#start_date = current_user.created_at
#end_date = Time.now
else
#start_date = Time.at(params[:start_date].to_i/1000)
#end_date = Time.at(params[:end_date].to_i/1000)
end
if params[:account] == 'all'
user_accounts = current_user.accounts.collect{ |a| a.id }
ActsAsTenant.without_tenant do
#conversations = Conversation.where(account_id: user_accounts).updated_between(#start_date,#end_date)
#users = current_user.accounts.collect{|account| account.users}.flatten.uniq.to_a
unassigned = User.new(name: 'Un-assigned')
#users << unassigned
end
else
account = Account.find(params[:account])
ActsAsTenant.with_tenant(account) do
#conversations = account.conversations.updated_between(#start_date,#end_date)
#users = account.users.to_a
unassigned = User.new(name: 'Un-assigned')
#users << unassigned
end
end
else
render json: {error: 'Invalid parameters'}, status: 422
end
end
here is the image of the data I want to be able to download as csv
https://i.stack.imgur.com/VI6lo.png
here is the leaderboard.json.jbuider
json.users #users do |user|
json.(user,:id, :name)
json.closed_count #conversations.where(user: user).closed.count
json.open_count #conversations.where(user: user).open.count
json.replies #conversations.where(user: user).inject(0){|sum, conversation| sum + conversation.messages.where(updated_at: #start_date..#end_date).where(direction: 'OUT').count}
json.resolution_time formatted_duration(array_mean(#conversations.closed.where(user: user).closed.collect{ |c| c.resolution_time }))
json.first_response Conversation.first_response(#conversations.where(user: user))
end
json.total_closed #conversations.closed.count
json.total_open #conversations.open.count
json.total_replies #conversations.inject(0){|sum, conversation| sum + conversation.messages.where(updated_at: #start_date..#end_date).where(direction: 'OUT').count}
json.start_date #start_date.to_i * 1000
json.end_date #end_date.to_i * 1000
How do I go about downloading it into a csv?

From your code snippet I'm not sure what you're trying to "export", but in general it should look like:
csv_lines = []
#some_data.each do |record|
csv_lines << "#{record.field1};#{record.field2};#{record.field3}" #and so on
end
#export csv_lines
txt = csv_lines.join "\n"

Related

How does recalling a variable work in a method?

I have the following method:
vendor_orders = VendorOrder.where(id: params[:vendor_order_ids])
orders = Order.find(vendor_orders.pluck(:order_id))
products = Product.joins(:vendor_product).where(vendor_products:{vendor_id: current_user.id }).ids #get all vendor_products that match current_user.vendor
line_items = LineItem.joins(:shop_product).where(cart_id: orders.pluck(:cart_id), fulfillment_status: "processing", shop_products: {product_id: products}).where.not(fulfillment_status: "canceled")
messages = []
n = 0
puts "line items: #{line_items.count}" #puts out 1
line_items.map do |li|
if li.update_attribute(:fulfillment_status, params[:mass][:fulfillment_status])
n+=1
else
messages << "#{vendor_order.vendor_order_token}"
end
end
puts "line items2: #{line_items.count}" #puts out 0
if n == line_items.count
flash.keep[:notice] = "Update for #{vendor_orders.count} order(s) and #{n} product(s) successful"
else
flash.keep[:notice] = "Failed update for Order: #{messages.join if messages.any?}"
end
puts "line item3 #{line_items.count}" #puts out 0
respond_to do |format|
format.html { redirect_to vendor_orders_path }
end
The question i have is about the puts
When calling line_items.count after I update the line_items to then not match the variable, does it recall line_items from above?
Is this true? I always assumed once something was defined and passed, it would stay at the rate, unless redefined.
Marek solved the issue by letting me know .count is a call to the database which will then call what you defined previously.
To solve this, I just use line_items_count = line_items.count and use that above any alterations to check against it.

How do I display database calls from Controller into view, to be viewed in HTML

I was handed a project from someone else, it's in Ruby On Rails, which I know VERY LITTLE. Basically, there is an EXPORT button, that the user clicks to send data to a CSV. I am tasked with sending this data to the view to be seen in HTML. (Thinking I could use dataTables). I have tried following examples, such as:
#example = StudentGroup.where(survey_id: #survey.id).order("groupNum")
and then using <%= #example %> in the view just to see the data and I get nothing. (Also extremely new to MySQL). I'll post the method, if ANYONE can help me, I'd very much appreciate it.
def download_results
if (user_signed_in?)
else
redirect_to new_user_session_path
end
#survey = Survey.find(params[:survey_to_view])
filename = #survey.name + " - " + Date.today.to_formatted_s(:short)
require "csv"
CSV.open(#survey.name+".csv", "wb") do |csv|
csv << [filename]
StudentGroup.where(survey_id: #survey.id).order("groupNum")
csv << []
csv << ["Summarized Results"]
csv << ["UCA","Group Number","Criteria 1","Criteria 2","Criteria 3","Criteria 4","Criteria 5","Criteria 6","Criteria 7","Criteria 8","Overall Team Contribution","Average(Would Work With Again)","Average(C1..C8)","Overall Team Contribution MINUS Average(C1..C9)"]
questions = #survey.questions
numQuestions = 0
questions.each do |q|
if(q.question_type != 2 && q.question_type != 4)
numQuestions = numQuestions+1
end
end
groups.each do |g|
answersCount = Answer.where(student_group_id: g.id).count
if(answersCount == numQuestions && answersCount != 0)
othersInGroup = StudentGroup.where(groupNum: g.groupNum, survey_id: #survey.id).order("groupNum")
size = othersInGroup.count-1
arr = []
criteria = SurveyQuestionDatum.where("number > 24 AND number < 35")
multiAvg = 0
teamCont = 0
criteria.each do |c|
avg = 0
othersInGroup.each do |o|
a = Answer.where(survey_question_datum_id: c.id, student_group_id: o.id).first
if(o.uca != g.uca)
if(a.nil?)
size = size-1
else
avg = avg + a.answer[g.uca].to_i
end
end
end
avg = avg.to_f/size
if(c.number == 33)
teamCont = avg
end
if(c.number < 33)
multiAvg = multiAvg+avg
end
arr << avg
end
multiAvg = multiAvg.to_f/8
arr << multiAvg
arr << teamCont-multiAvg
arr.insert(0,g.uca, g.groupNum)
csv << arr
end
end
csv << []
csv << []
csv << ["Raw Student Answers"]
groups = StudentGroup.where(survey_id: #survey.id).order("groupNum")
size = groups.count
csv << ["UCA", "F-Number", "Group Number"]
groups.each do |g|
answersCount = Answer.where(student_group_id: g.id).count
if(answersCount == numQuestions && answersCount != 0)
othersInGroup = StudentGroup.where(groupNum: g.groupNum, survey_id: #survey.id).order("groupNum")
csv << []
csv << [g.uca, g.FNum, g.groupNum]
answers = Answer.where(student_group_id: g.id)
csv << ["Question Number", "Question", "Answer"]
answers.each do |a|
datum = a.survey_question_datum
question = datum.question
#question_types = {"0" => "short", "1" => "paragraph",
#2" => "title", "3" => "fivept", "4" => "fixed",
#5" =>"ranking", "6"=>"tenpoints","7"=>"hundredpoints"}
ansText = ""
if(question.question_type == 0)
ansText = a.answer
elsif (question.question_type == 1)
if(question.rule == 'perMember')
othersInGroup.each do |o|
ansText = ansText+"#{o.uca},#{a.answer[o.uca]},"
end
elsif(question.rule == 'default')
ansText = a.answer
end
else (question.question_type == 3)
othersInGroup.each do |o|
ansText = ansText+"#{o.uca},#{a.answer[o.uca]},"
end
end
ansText = ansText.chomp(',')
ansText = ansText.split(',')
ansText.insert(0,datum.number,question.question_text)
csv << ansText
end
end
end
end
send_file(#survey.name+".csv", :filename => filename+".csv")
end
You need a new controller action. Take a look at http://guides.rubyonrails.org/layouts_and_rendering.html
Create an index (or show, or whatever you want to call it, maybe example) action. Make sure it is in your routes.
http://guides.rubyonrails.org/getting_started.html#adding-a-route-for-comments
do not use the download_results code.
set your #example variable the way you were trying to do.
create a view for your index action
add the data to your index view.
If you put code in your download_results method (action) it will never get rendered because of the send_file method call.
Did you create a brand new controller / action / view? Did you use generators? Have you really practiced doing this setup exactly the way the examples, videos, tutorials say to do it? If you have, you have seen how all the pieces (models, controllers, actions, views) come together. You should have seen how render statements come into play. Do that, exactly as the tutorials say to do it and you will get the idea.
If you want to use the same content that the download action uses, refactor the code to extract a method that is used both actions.
This is related to respond_to part, check the docs.
send_file(#survey.name+".csv", :filename => filename+".csv")
Your code above simply means you click the button, the controller will respond you with a csv file. So, if you want a html, the controller should be able to respond to html as well.

i have a loop that is not working on ruby on rails

I have loop that is checking if there is no image display a dummy image. I don't know what is wrong with this loop. It is not display the dummy image.Any help will be appreciated. Thank you
.col-md-12
- #applied_users.each do |user|
.applied
%a
%a.litle-modules.pull-left{href: show_user_public_path(user.id, ((Apply.where user_id: user.id, job_id: #job.id).first).id)}
.col-xs-6.col-md-5
.thumbnail
- if user.image != nil
= image_tag "profile_pic.jpeg"
- elsif user.image.nil?
= image_tag "profile_pic.jpeg"
.col-md-7.pull-right
%h2= user.fname
%p= user.location
%p= user.description
def show_private
#this method is responsible for showing the companies their job application page after matches have been made and after people have applied.
neo_results_array = []
percentage_match = []
#job = Job.find(params[:id])
#neo_results = Neo4jProcess.match_users(#job.id, 20000)
filtered_results = JSON.parse(#neo_results)
users = filtered_results["users"]
users.each do |user|
if user["score"] >= 0.005
neo_results_array << user["user_id"]
percentage_match << user["score"]
else
end
end
#final_array = neo_results_array.zip(percentage_match)
print #final_array
if #job.applies == [] && neo_results_array == []
redirect_to share_page_path(#job.id)
else #job.applies != [] || neo_results_array != []
applied = #job.applies.pluck(:user_id)
#applied_users = User.find(applied)
percentage_user_array = []
#final_array.each do |item|
percentage_user_array << item[0]
end
#matched_users = User.find(percentage_user_array)
end
end
just edited. here you can see my controller responsible for the img and other things
Remove condition from else
If you want to put some conditions for else as well use
elsif user.image.nil?

Cant found model with out an ID in rails 3.2.12

i ve this method. I m not at all able to understand the error which is
Couldn't find Company without an ID
in ActiveRecord::RecordNotFound in CustomersController#bulk_create
This method is written to create customers for a company in bulk by taking their name and numbers in format name:number.
The method is as follows:
def bulk_create
res = ""
comp_id = params[:customer][:selected_companies].delete_if{|a| a.blank?}.first
comp = Company.find(comp_id)
s = SentSmsMessage.new
s.set_defaults
s.data = tmpl("command_signup_ok", customer, comp) unless params[:customer][:email].length > 0
s.data = params[:customer][:email] if params[:customer][:email].length > 0
s.company = comp if !comp.nil?
s.save
unless comp_id.blank?
params[:customer][:name].lines.each do |line|
(name, phone) = line.split(/\t/) unless line.include?(":")
(name, phone) = line.split(":") if line.include?(":")
phone = phone.gsub("\"", "")
phone = phone.strip if phone.strip.to_i > 0
name = name.gsub("\"", "")
name = name.gsub("+", "")
phone = "47#{phone}" if params[:customer][:active].to_i == 1
customer = Customer.first(:conditions => ["phone_number = ?", phone])
if customer.nil?
customer = Customer.new
customer.name = name
# customer.email
# customer.login
# customer.password
customer.accepted_agreement = DateTime.now
customer.phone_number = phone
customer.active = true
customer.accepted_agreement = DateTime.now
customer.max_msg_week = params[:customer][:max_msg_week]
customer.max_msg_day = params[:customer][:max_msg_day]
customer.selected_companies = params[:customer][:selected_companies].delete_if{|a| a.blank?}
res += "#{name} - #{phone}: Create OK<br />" if customer.save
res += "#{name} - #{phone}: Create failed<br />" unless customer.save
else
params[:customer][:selected_companies].each do |cid|
new_company = Company.find(cid) unless cid.blank?
if !new_company.nil?
if !customer.companies.include?(new_company)
customer.companies << new_company
if customer.save
res += "#{name} - #{phone}: Customer exists and the customer was added to the firm #{new_company.name}<br />"
else
res += "#{name} - #{phone}: Customer exist, but something went wrong during storage. Check if the client is in the firm.<br />"
end
else
res += "#{name} - #{phone}: Customer exists and is already on firm #{new_company.name}<br />"
end
end
end
end
s.sms_recipients.create(:phone_number => customer.phone_number)
end
s.save
s.send_as_sms
#result = res
respond_to do |format|
format.html { render "bulk_create"}
end
else
#result = "You have not selected any firm to add these users. Press the back button and try again."
respond_to do |format|
format.html { render "bulk_create"}
end
end
end
I want to update one situation here. That when i submit the form blank then it gives this error. Also if i filled the form with the values then its show the situation which the method is returning in case of fail.
res += "#{name} - #{phone}: Create failed <br />"
The tmpl method
private
def tmpl(setting_name, customer, company = nil)
text = ""
if customer.companies.count > 0
sn = "#{setting_name}_#{#customer.companies.first.company_category.suffix}".downcase rescue setting_name
text = Setting.value_by(sn) rescue ""
end
textlenth = text.length rescue 0
if textlenth < 3
text = Setting.value_by(setting_name) rescue Setting.value_by("command_error")
end
return fill_template(text, customer, company)
end
From the model customer.rb
def selected_companies=(cmps)
cmps.delete("")
# Check the old ones. Make a note if they are not in the list. If the existing ones are not in the new list, just remove them
self.companies.each do |c|
self.offer_subscriptions.find(:first, ["customer_id = ?", c]).destroy unless cmps.include? c.id.to_s
cmps.delete c.id.to_s if cmps.include? c.id.to_s
end
# Then create the new ones
cmps.each do |c2|
cmp = Company.find(:first, ["id = ?", c2])
if cmp && !c2.blank?
offerSubs = offer_subscriptions.new
offerSubs.company_id = c2
offerSubs.save
end
end
end
def selected_companies
return self.companies.collect{|c| c.id}
end
The association of customer is as follows:
has_many :offer_subscriptions
has_many :companies, :through => :offer_subscriptions
This code is written by the some one else. I m trying to understand this method but so far not being able to understand this code.
Please help.
Thanks in advance.
You are getting 'Couldn't find Company without an ID' error because your Company table doesn't contain record with id = comp_id
Change comp = Company.find(comp_id) to comp = Company.find_by_id(comp_id).
This will return nil instead of an error.
Add comp is not nil condition is already handled in your code.
Your comp_id line is returning nil.
comp_id = params[:customer][:selected_companies].delete_if{|a| a.blank?}.first
Post the params that get passed to this function and we could hopefully find out why. In the meantime you could enclose the block in a begin - rescue block to catch these errors:
begin
<all your code>
rescue ActiveRecord::RecordNotFound
return 'Unable to find a matching record'
end
try this:
comp = ""
comp = Company.find(comp_id) unless comp_id.nil?
instead of comp = Company.find(comp_id)
further nil checking present in your code.
Reason being
params[:customer][:selected_companies].delete_if{|a| a.blank?} = []
so [].first = nil
therefor, params[:customer][:selected_companies].delete_if{|a| a.blank?}.first = nil
and comp_id is nil
So check the log file and check what is coming in the parameter "selected_companies"
when you will find the parameter, everything will be understood well....

Rails - Fetch results on the basis of number of params in query string

I am working on an events application where i want to filter events depending on the 3 parameters location or starts_at or ends_at in the query string. There can be any one, two or all the parameters in the query string. In i use if-else statement i need to make 6 cases which will make my code clumsy. Rather i am thinking to implement something this way:
class EventsController < ApplicationController
def index
unless params.empty?
unless params[:location].nil?
#events = Event.where("location = ?", params[:location])
end
unless params[:starts_at].nil?
unless #events.empty?
#events = #events.where("start_date = ?", params[:start_date])
else
#events = Event.where("Date(starts_at) = Date(?)", params[:starts_at])
end
end
unless params[:ends_at].nil?
unless #events.empty?
#events = #events.where("end_date = ?", params[:end_date])
else
#events = Event.where("Date(ends_at) = Date(?)", params[:ends_at])
end
end
end
end
end
But this code doesnt work since where query doen not work on an array. Can someone suggest me some solution for this..
You should be able to pass your params hash directly to where, and it will form the correct SQL based on the keys and values of that hash:
Event.where(params)
An example in the console:
1.9.3p194 :001 > puts Example.where(:location => 'here', :started_at => '2012-08-13').to_sql
SELECT "examples".* FROM "examples" WHERE "examples"."location" = 'here' AND "examples"."started_at" = '2012-08-13'
Try Following
def index
unless params.empty?
where_array, arr = [], []
if params[:location]
where_array << "location = ?"
arr << params[:location]
end
if params[:starts_at]
where_array << "start_date = ?"
arr << params[:starts_at]
end
if params[:ends_at]
where_array << "end_date = ?"
arr << params[:ends_at]
end
#events = arr.blank? ? [] : Event.where([where_array.join(" AND "), *arr])
end
end

Resources