I have several conditions in my search.
#events = Event.search(params[:search],
:conditions => {:group_size => 1, :days => 1})
The above code is working fine. However, if I want to replace the hash with a private method, I get syntax error
syntax error, unexpected ',', expecting tASSOC
:conditions => {group_size_condition, :days => 1},
Code is as follow
#events = Event.search(params[:search],
:conditions => {group_size_condition, :days => 1})
private
def group_size_condition
if params[:groupsize] == 'single (1)'
:group_size => 1
elsif params[:groupsize] == 'couple (2)'
:group_size => 2
elsif params[:groupsize] == 'small group(3-5)'
:group_size => 3..5
else
nil
end
end
Thanks in advance
That will be work
#events = Event.search(params[:search],
:conditions => group_size_condition.merge(:days => 1))
private
def group_size_condition
case params[:groupsize]
when 'single (1)' then {:group_size => 1}
when 'couple (2)' then {:group_size => 2}
when 'small group(3-5)' then {:group_size => 3..5}
else
{}
end
end
I think you missed :group_size key
#events = Event.search(params[:search],
:conditions => {:group_size => group_size_condition, :days => 1})
I think perhaps you want to actually pass the string, as in:
def group_size_condition
if params[:groupsize] == 'single (1)'
':group_size => 1'
elsif params[:groupsize] == 'couple (2)'
':group_size => 2'
elsif params[:groupsize] == 'small group(3-5)'
':group_size => 3..5'
else
nil
end
end
Related
I'm trying to import 90k lines of xml into my ruby app. herokus timeout limit is 30s so i'm trying to use delayed job.
The import class works wonderfully in around 48-hippopotomuses locally. When i add the line
handle_asynchronously :save_races
I get the error "undefined method save_races' for classXmltube'"
What am i doing wrong with DJ and how can i get this to work?
Full class code below
require "rexml/document"
class Xmltube
def self.convert_save(xml_data)
doc = REXML::Document.new xml_data.read
doc.elements.each("Meeting") do |meeting_element|
meeting = save_meeting(meeting_element)
save_races(meeting_element, meeting)
Rails.logger.info "all done"
end
end
def self.save_races(meeting_element, meeting)
meeting_element.elements.each("Races/Race") do |race_element|
race = save_race(race_element, meeting)
save_race_entrants(race_element, race)
end
end
def self.save_race_entrants(race_element, race)
race_element.elements.each("RaceEntries/RaceEntry") do |entry_element|
horse = save_horse(entry_element)
jockey = save_jockey(entry_element)
start = save_start(entry_element, horse, jockey, race)
save_sumaries(entry_element, start)
end
end
def self.save_track(meeting_element)
# there is only one track, but still, each? wtf.
t = {}
meeting_element.elements.each("Track") do |track|
t = {
:name => track.attributes["VenueName"],
:track_code => track.attributes["VenueCode"],
:condition => track.elements['TrackRating'].text,
:club_id => save_club(meeting_element.elements["Club"]).id
}
end
track = Track.where(:track_code => t[:track_code] ).first
if track
Track.update(track.id, t)
else
Track.create(t)
end
end
def self.save_meeting meeting_element
t = {
:meet_code => meeting_element.attributes['MeetCode'],
:stage => meeting_element.elements["MeetingStage"].text,
:phase => meeting_element.elements["MeetingPhase"].text,
:nominations_close_at => meeting_element.elements["NominationsClose"].text,
:acceptance_close_at => meeting_element.elements["AcceptanceClose"].text,
:riders_close_at => meeting_element.elements["RidersClose"].text,
:weights_published_at => meeting_element.elements["WeightsPublishing"].text,
:club_id => save_club(meeting_element.elements["Club"]).id ,
:track_id => save_track(meeting_element).id,
:tab_status => meeting_element.elements["TabStatus"].text,
:state => meeting_element.elements["StateDesc"].text,
:day_night => meeting_element.elements["DayNight"].text,
:number_of_races => meeting_element.elements["NumOfRaces"].text,
:meet_date => meeting_element.elements["MeetDate"].text,
}
meeting = Meeting.where(:meet_code => t[:meet_code] ).first
if meeting
Meeting.update(meeting.id, t)
else
Meeting.create(t)
end
end
############################################################
def self.save_sumaries entry_element, start
entry_element.elements.each('Form/ResultsSummaries/ResultsSummary') do | element |
s = {
:name => element.attributes['Name'],
:start_id => start.id,
:starts => element.attributes['Starts'],
:wins => element.attributes['Wins'],
:seconds => element.attributes['Seconds'],
:thirds => element.attributes['Thirds'],
:prize_money => element.attributes['PrizeMoney'],
}
sum = Summary.where(:name => s[:name] ).where(:start_id => s[:start_id]).first
if sum
Summary.update(sum.id, s)
else
Summary.create(s)
end
end
end
def self.save_start entry_element, horse, jockey, race
s = {
:horse_id => horse.id,
:jockey_id => jockey.id,
:race_id => race.id,
:silk => entry_element.elements["JockeySilksImage"].attributes["FileName_NoExt"],
:start_code => entry_element.attributes['RaceEntryCode'],
:handicap_weight => entry_element.elements['HandicapWeight'].text,
}
# Rails.logger.info entry_element['HandicapWeight'].text
start = Start.where(:start_code => s[:start_code] ).first
if start
Start.update(start.id, s)
else
Start.create(s)
end
end
def self.save_jockey entry_element
j={
:name => entry_element.elements['JockeyRaceEntry/Name'].text,
:jockey_code => entry_element.elements['JockeyRaceEntry'].attributes["JockeyCode"],
}
jockey = Jockey.where(:jockey_code => j[:jockey_code] ).first
if jockey
Jockey.update(jockey.id, j)
else
Jockey.create(j)
end
end
def self.save_horse entry_element
trainer = save_trainer entry_element
h= {
:name => entry_element.elements['Horse'].attributes["HorseName"],
:color => entry_element.elements['Horse'].attributes["Colour"],
:dob => entry_element.elements['Horse'].attributes["FoalDate"],
:sex => entry_element.elements['Horse'].attributes["Sex"],
:trainer_id => trainer.id,
:horse_code => entry_element.elements['Horse'].attributes["HorseCode"],
}
horse = Horse.where(:horse_code => h[:horse_code] ).first
if horse
Horse.update(horse.id, h)
else
Horse.create(h)
end
end
def self.save_trainer entry_element
t= {
:name => entry_element.elements['Trainer/Name'].text,
:trainer_code => entry_element.elements['Trainer'].attributes["TrainerCode"]
}
trainer = Trainer.where(:trainer_code => t[:trainer_code] ).first
if trainer
Trainer.update(trainer.id, t)
else
Trainer.create(t)
end
end
def self.save_club element
t = {}
t = {
:club_code => element.attributes['ClubCode'],
:title => element.attributes["Title"],
}
club = Club.where(:club_code => t[:club_code] ).first
if club
Club.update(club.id, t)
else
Club.create(t)
end
end
def self.save_race element, meeting
r = {
:name => element.elements['NameRaceFull'].text,
:occur => element.elements['RaceStartTime'].attributes["TimeAtVenue"],
:distance => element.elements['RaceDistance'].text,
:race_type => element.elements['RaceType'].text,
:track_id => meeting.track_id,
:race_code => element.attributes["RaceCode"],
:meeting_id => meeting.id
}
race = Race.where(:race_code => r[:race_code] ).first
if race
Race.update(race.id, r)
else
Race.create(r)
end
end
handle_asynchronously :save_races
end
Since your save_races is a class method, you should call handle_asynchronously on Xmltube's singleton class:
class << self
handle_asynchronously :save_races
end
This just worked as I would expect
class Foo
def self.bar(s)
Rails.logger.info "From Foo.bar('#{s}')"
end
end
# then ...
Foo.delay.bar('hello')
I was running 4.0.4 of DJ with ruby 2.1
This is my code:
def return_rider_values(pol_option, pro_endorsement, prop_coverage, *par)
rider_values
par.each do |p|
rider_values << RiderValue.find_all_by_rider_id(p)
end
rider_hash = { }
rider_values.each do |rv|
if rv.attributes["name"].downcase == "yes"
rider_hash.merge!({par[0].to_s => rv.attributes['id'].to_s})
elsif rv.attributes["position"] == pol_option.to_i && rv.attributes["rider_id"] == par[1]
rider_hash.merge!({par[1].to_s => rv.attributes["id"].to_s})
elsif rv.attributes["position"] == prop_coverage.to_i && rv.attributes["rider_id"] == par[2]
rider_hash.merge!({par[2].to_s => rv.attributes["id"].to_s})
elsif rv.attributes["position"] == pro_endorsement.to_i && rv.attributes["rider_id"] == par[3]
rider_hash.merge!({par[3].to_s => rv.attributes["id"].to_s})
end
end
rider_hash
end
The output looks like this:
rider_hash #=> '22' -> 58
'23' -> 61
'25' -> 66
'26' -> 68
I was expecting, and need apparently since it's not working later down the line:
rider_hash #=> '22' -> '58'
'23' -> '61'
'25' -> '66'
'26' -> '68'
I don't know why the lookup function later in the program wants the ids to be strings instead of ints. I just know that it does, and I can't change it since lots of other methods use it.
I have to_s on both the hash key and value. I realize that in Ruby 1.9 to_s is an alias for inspect but even in the Hash documentation it says that, inspect or to_s is supposed to "Return the contents of this hash as a string."
So why is only the key being returned as a string?
You have an array of hashes so try this:
def return_rider_values
par = [1,2,3,6]
rider_hash = {}
rider_values = [element1: {:attributes => {:id => 1, :name => 'yes', :position => 1, :rider_id => 1}},
element2: {:attributes => {:id => 2, :name => 'no', :position => 2, :rider_id => 2}},
element3: {:attributes => {:id => 3, :name => 'something', :position => 1, :rider_id => 3}},
element4: {:attributes => {:id => 4, :name => 'something_else', :position => 2, :rider_id => 6}}]
rider_values.each_with_index do |hash, idx|
rider_values[idx].each_pair do |k, v|
if v[:attributes][:name].downcase == "yes"
rider_hash.merge!({par[0].to_s => v[:attributes][:id].to_s})
elsif v[:attributes][:position] == 2 && v[:attributes][:rider_id] == par[1]
rider_hash.merge!({par[1].to_s => v[:attributes][:id].to_s})
elsif v[:attributes][:position] == 3 && v[:attributes][:rider_id] == par[2]
rider_hash.merge!({par[2].to_s => v[:attributes][:id].to_s})
elsif v[:attributes][:position] == 4 && v[:attributes][:rider_id] == par[3]
rider_hash.merge!({par[3].to_s => v[:attributes][:id].to_s})
end
end
end
rider_hash
end
test = return_rider_values
puts test
output: #=> {"1"=>"1", "2"=>"2"}
I ended up getting what I wanted by adding this:
rider_hash.each{ |_,v| v.replace "'#{v}'"}
But this seems like a dirty solution somehow.
Hi i have a controller in rails but it gives me an error
ActiveRecord::StatementInvalid in StreamsController#front_page
Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'EPOCH FROM posts.created_at) - 1327654606)/9000) desc LIMIT 15' at line 1: SELECT `posts`.* FROM `posts` WHERE ((`posts`.`featured` = 1 OR `posts`.`author_id` = 5)) ORDER BY (ln( 1 + posts.likes_count) + (EXTRACT(EPOCH FROM posts.created_at) - 1327654606)/9000) desc LIMIT 15
The StreamsController#front_page are:
def front_page
stream_responder do
#stream = Stream::FrontPage.new(current_user, params[:offset])
#stream_json = PostPresenter.collection_json(#stream.stream_posts, current_user, lite?: true, include_root: false)
end
end
And PostPresenter
require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'template_picker')
class PostPresenter
include ActionView::Helpers::TextHelper
attr_accessor :post, :current_user
def initialize(post, current_user=nil)
#post = post
#current_user = current_user
#person = #current_user.try(:person)
end
def self.collection_json(collection, current_user, opts={})
collection.includes(:author => :profile).map {|post| self.new(post, current_user).as_json(opts)}
end
def as_json(options={})
{
:id => #post.id,
:guid => #post.guid,
:text => #post.raw_message,
:plain_text => #post.plain_text,
:public => #post.public,
:featured => #post.featured,
:created_at => #post.created_at,
:staff_picked_at => #post.staff_picked_at,
:interacted_at => #post.interacted_at,
:tags => #post.tags.as_json,
:tag_list => #post.tags.map(&:name).join(", "),
:post_type => #post.post_type,
:image_url => #post.image_url,
:object_url => #post.object_url,
:favorite => #post.favorite,
:nsfw => #post.nsfw,
:author => PersonPresenter.new(#post.author, current_user),
:o_embed_cache => #post.o_embed_cache.try(:as_api_response, :backbone),
:mentioned_people => [],
:photos => #post.photos.map {|p| p.as_api_response(:backbone)},
:frame_name => #post.frame_name || template_name,
:parent => (options.fetch(:include_root, true) ? parent(options) : nil),
:title => title,
:next_post => next_post_path,
:previous_post => previous_post_path,
:screenshot_url => #post.screenshot_url,
:screenshot_width => #post.screenshot_width,
:screenshot_height => #post.screenshot_height,
:show_screenshot => self.show_screenshot?,
:has_gif => self.has_gif?,
:conversation_id => #post.conversation_id,
:interactions => options.fetch(:lite?, false) ? lite_interactions : heavy_interactions,
:original => #post.original?
}
end
def next_post_path
Rails.application.routes.url_helpers.next_post_path(#post)
end
def previous_post_path
Rails.application.routes.url_helpers.previous_post_path(#post)
end
def heavy_interactions
PostInteractionPresenter.new(#post, current_user).as_json
end
def lite_interactions
PostInteractionPresenter::Lite.new(#post, current_user).as_json
end
def title
#post.text.present? ? truncate(#post.plain_text, :length => 118) : I18n.translate('posts.presenter.title', :name => #post.author.name)
end
def template_name #kill me, lol, I should be client side
#template_name ||= TemplatePicker.new(#post).template_name
end
def parent(opts={})
PostPresenter.new(#post.parent, current_user).as_json({:include_root => false}.merge(opts)) if #post.respond_to?(:parent) && #post.parent.present?
end
def show_screenshot?
#post.screenshot_url.present?
end
def has_gif?
return false unless #post.photos.present?
return 'gif' if #post.photos.detect{ |p| p.url && p.url.match(".gif") }.present?
end
protected
def person
#current_user.person
end
def user_signed_in?
#current_user.present?
end
end
I dont know where am i do wrong..? badly need help on this
You're closing an unopened parenthesis in the query.
'EPOCH FROM posts.created_at) ...'
I am fairly still new to ruby on rails and don't fully understand why I am getting the following error:
undefined local variable or method `user' for #<StatisticsController:0xb9a20d0>
The code:
class StatisticsController < ApplicationController
before_filter :authenticate, :only => [:index]
def index
#title = "Statistics"
#projects = Project.all
#data = []
Project.all.each do |project|
projdata = { 'name' => project.project_name.to_s,
'values' => [] }
['Pre-Sales','Project','Fault Fixing','Support' ].each do |taskname|
record = Effort.sum( :hours,
:joins => {:project_task => {:efforts => :user}},
:conditions => { "project_tasks.efforts.user_id" => user.id,
"project_tasks.project_id" => project.id,
"project_tasks.task_name" => taskname } )
projdata[ 'values' ].push( record )
end
#data.push( projdata )
end
end
end
Update
class StatisticsController < ApplicationController
before_filter :authenticate, :only => [:index]
def index
#title = "Statistics"
#projects = Project.all
#data = []
User.all.each do |user|
projdata = { 'name' => user.user_id.to_s,
'values' => [] }
['Pre-Sales','Project','Fault Fixing','Support' ].each do |taskname|
user = User.all
record = Effort.sum( :hours,
:joins => {:project_task => {:efforts => :user}},
:conditions => { "project_tasks.efforts.user_id" => user.id,
"project_tasks.project_id" => project.id,
"project_tasks.task_name" => taskname } )
projdata[ 'values'].push( record )
end
#data.push( projdata )
end
end
end
In string :conditions => { "project_tasks.efforts.user_id" => user.id, you call id for user object, but it is not instantiated in code above.
Your update doesn't loop over the users at all; user is now a collection of all the users. You need to iterate over the users if you want to get individual statistics for individual users.
Are you using devise? Use current_user instead of user.
Fix of your code:
User.all.each do |user|
projdata = { 'name' => user.user_id.to_s,
'values' => [] }
['Pre-Sales','Project','Fault Fixing','Support' ].each do |taskname|
record = Effort.sum( :hours,
:joins => {:project_task => {:efforts => :user}},
:conditions => { "project_tasks.efforts.user_id" => user.id,
"project_tasks.project_id" => project.id,
"project_tasks.task_name" => taskname } )
projdata[ 'values'].push( record )
end
#data.push( projdata )
end
So: removed the rogue user=User.all :)
Question: in 1 place you write user.user_id and in the other you write user.id. Is that correct?
baza_managers = BazaManager.find(:all,
:conditions => ["or_unit_id != ?", 1]).collect {
|mou| [mou.email, mou.or_unit_id]}
respondent_emails = Respondent.find(:all).collect {|r| r.email }
ERROR:
from lib/scripts/baza_sync.rb:26:in `each'
from lib/scripts/baza_sync.rb:26
26 line ↓
baza_managers.each do |moi|
if !respondent_emails.include?(moi)
Respondent.create(:email => moi, :user_id => 1, :respondent_group_id => moi)
end
end
ERROR I GET:
undefined method `email' for ["vadasd#test.test.com", 8]:Array (NoMethodError)
I don't know why I'm getting this error.
try with:
baza_managers = BazaManager.find(:all,
:conditions => ["or_unit_id != ?", 1]).collect {
|mou| [mou.email, mou.or_unit_id]}
respondent_emails = Respondent.find(:all).collect {|r| r.email }
baza_managers.each do |moi|
if !respondent_emails.include?(moi[0])
Respondent.create(:email => moi[0], :user_id => 1, :respondent_group_id => moi[1])
end
end
Fix your code with following:
if !respondent_emails.include?(moi[0])
Respondent.create(:email => moi[0], :user_id => 1, :respondent_group_id => moi[1])
end
I would think there is at least one error not in the way you are using collect but in the logic you write on the last lines when you go through the baza_managers array.
With this code the condition respondent_emails.include?(moi) will be always false because respondent_emails is an array of email addresses but moi is an array like ["vadasd#test.test.com", 8] so they will never match.
I think this mistake made you make an error in the line :
Respondent.create(:email => moi, :user_id => 1, :respondent_group_id => moi)
Because this line will be evaluate as (for example) :
Respondent.create(:email => ["vadasd#test.test.com", 8], :user_id => 1, :respondent_group_id => ["vadasd#test.test.com", 8])
Which is probably not what you want.
Last, I would suggest you to read the debugger rails guide, I often use debugger to figure out where and what is the problem in this kind of code and error.
I would rewrite your code as follows:
baza_managers = BazaManager.all(:conditions => ["or_unit_id != ?", 1]).
collect { |mou| [mou.email, mou.or_unit_id]}
respondent_emails = Respondent.find(:all).collect {|r| r.email }
baza_managers.each do |email, unit_id|
unless respondent_emails.include?(email)
Respondent.create(:email => email, :user_id => 1,
:respondent_group_id => unit_id)
end
end
This solution can be further optimized by using OUTER JOIN to detect missing Respondents
BazaManager.all(
:include => "OUTER JOIN respondents A ON baza_managers.email = A.email",
:conditions => ["baza_managers.or_unit_id != ? AND A.id IS NULL", 1]
).each do |bm|
Respondent.create(:email => bm.email, :respondent_group_id => bm.or_unit_id,
:user_id => 1)
end
The solution can be made elegant and optimal by adding associations and named_scope.
class BazaManager
has_many :respondents, :foreign_key => :email, :primary_key => :email
named_scope :without_respondents, :include => :respondents,
:conditions =>["baza_managers.or_unit_id != ? AND respondents.id IS NULL", 1]
end
Now the named_scope can be used as follows:
BazaManager.without_respondents.each do |bm|
Respondent.create(:email => bm.email, :respondent_group_id => bm.or_unit_id,
:user_id => 1)
end