How can I rewrite this below code with rails 4 new syntax.
Tracker.find(:all, :joins => :projects,
:select => "DISTINCT #{Tracker.table_name}.*",
:conditions => ["#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> #{STATUS_ARCHIVED}", lft, rgt],
:order => "#{Tracker.table_name}.position")
Below is the equivalent way :
Tracker.joins(:projects)
.where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> #{STATUS_ARCHIVED}", lft, rgt)
.select("DISTINCT #{Tracker.table_name}.*")
.order("#{Tracker.table_name}.position")
Related
Okay, at the moment I have the following in my model:
has_many :current_monitorings, :class_name => "Monitoring",
:conditions => proc { [ 'monitorings.created_at > ?', Time.now.midnight ] }
I want to add a condition to this that checks if the outlet is_active attribute is set to false. I tried doing it like this:
has_many :current_monitorings, :class_name => "Monitoring",
:conditions => proc { [ 'monitorings.created_at > ? AND outlet.is_active = ?', Time.now.midnight, 'false' ] }
However, this doesn't work. I'm probably being stupid, but any help is greatly appreciated!
In your sql, outlet.is_active should be outlets.is_active. Assuming is_active is a boolean field, just pass false and not "false":
Try this:
has_many :monitorings
def current_monitorings
monitorings.joins(:outlets).where(
'monitorings.created_at > ? AND outlets.is_active = ?',
Time.now.midnight,
false
)
end
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
Contract.all(:conditions => ['voided == ?', 0]).size
=> 364
Contract.all(:conditions => ['voided != ?', 0]).size
=> 8
Contract.all.size
=> 441
the 3 numbers does not added up (364 + 8 != 441). What's the proper way write the :conditions to count the rows which the voided column value is NULL or equal to zero?
Contract.all(:conditions => {:voided => nil})
or
Contract.all(:conditions => ['voided IS NULL'])
Contract.all(:conditions => ["voided is ?", nil]).size
Contract.all(:conditions => ["voided is not ?", nil]).size
I need to select some dynamic price ranges submitted from a search form. How should I approach this with scopes? I am looking for something like this
Painting.price_range(['1..500', '2000..5000'])
SELECT * FROM paintings WHERE price BETWEEN 1..500 **OR** BETWEEN 2000..5000 etc.
Best regards.
Asbjørn Morell.
named_scope :price_range, :conditions => ["(price BETWEEN 1 AND 500) OR (price BETWEEN 2000 AND 5000)"]
OR
named_scope :price_range, :conditions => ["(price ?) OR (price ?)", (1..500).to_s(:db), (2000..5000).to_s(:db)]
Dynamic
named_scope :price_between, lambda { |from, to| { :conditions => ['price > ? AND price <= ?', from, to] } }
named_scope :price_between, lambda { |from, to| { :conditions => ['price BETWEEN ? AND ?', from, to] } }
->
MyModel.price_between(1,100)
You'll need to use a lambda on the named_scope. The following should work:
named_scope :price_range, lambda { |ranges|
{
:conditions => ["(" +
ranges.collect {"price between ? and ?"}.join(" or ") +
")"] +
ranges.collect {|r| [r.min, r.max]}.flatten
}
}
The first ranges.collect creates as many "between ? and ?" checks as you have ranges and then the second ranges.collect flattens out the ranges and adds them as values to be sanitized into the conditions. I've stuck brackets round the ors just to be on the safe side.
Where is the error in this I can't see it:
news = News.find(:all, :conditions => [":simulation_id => session[:sim_id] AND :created_at > session[:last_login]"])
Try this:
news = News.find(:all, :conditions => ["simulation_id = ? AND created_at > ?", session[:sim_id], session[:last_login]])
Your conditions string won't be evaluated as you expect:
[":simulation_id => session[:sim_id] AND :created_at > session[:last_login]"]
change that to
["simulation_id = ? AND created_at > ?", session[:sim_id], session[:last_login]]
You can also call Model.all instead of Model.find(:all) which would look something like this:
news = News.all(:conditions => ["simulation_id = ? AND created_at > ?", session[:sim_id], session[:last_login]])