I have a Reservation model that I'm searching for with three fields. The container_id must always be self.id but as confirmed and auto_confirmed only one needs to be true. I have the following but it doesn't perform what I need:
Reservation.find(:all,
:conditions => ['container_id = ? AND confirmed = ? OR auto_confirm = ?',
self.id, true, true,])
How should I change this?
I'm not sure I'm getting your problem, but from what I understand this would work:
Reservation.find(:all,
:conditions => ['container_id = ? AND (confirmed = ? OR auto_confirm = ?)',
self.id, true, true,])
As per your question confirmed and auto_confirmed only one needs to be true. So use following
Reservation.find(:all,
:conditions => ['container_id = :container AND
( (confirmed = :flag and auto_confirm != :flag) ||
(confirmed != :flag and auto_confirm = :flag))',
{:container=> self.id, :flag=>true}]
)
I'm not sure if this is database agnostic, but you could try
Reservation.find(:all,
:conditions => ['container_id = ? AND confirmed = ? **XOR** auto_confirm = ?',
self.id, true, true,])
What you are saying is not true - a query like
SELECT * FROM foos WHERE content_id = 345 AND (confirm = 1 OR auto_confirm = 1)
will select the rows where both "confirm" columns are set to 1 (and ActiveRecord creates tinyint columns for booleans and checks against 1 and 0).
If you mean "find all rows matching on the content_id and having EITHER confirmed OR auto_confirmed true but NOT both" then you come down to a query like this
SELECT * FROM foos WHERE content_id = 345 AND ((confirmed = 1 AND auto_confirm = 0) OR (confirmed = 0 AND auto_confirm = 1))
which you reword in AR terms like this
Reservation.find(:all,
:conditions => [
'container_id = ? AND ((confirmed = 1 AND auto_confirm != 1) OR (confirmed = 0 AND auto_confirm != 1))',
self]
)
However, judging from the names your fields have you are actually implementing a state machine with separate columns which will bring you pain, so I'd investigate something that would give you progressions of states instead of checking for separate on and off bits.
I think something like this:
Reservation.find(:all,
:conditions => ['container_id = ? AND ((confirmed != true AND auto_confirm = true) OR (confirmed = true AND auto_confirm != true))',
self.id])
Related
Well, as maybe you know guys, in redmine base sturcture there are tables issues, projects. I never used to write code in ruby before btw. But I got task, so.
Here the issues table structure:
And here is the project table structure:
The problem is I need to get all issues where project_id equals #project and project.parent_id equals #project too.
The problem is, first I don't understand what current #project contents. Second I got no idea how to access to the #project's parent_id field here. Parent_id is referenced to the project.id field by the way.
I got ruby function here.
Boss said I need to edit scope variable. So I trying to edit it like this:
def find_no_version_issues
#backlog_version = #project.versions.open.where("LOWER(#{Version.table_name}.name) LIKE LOWER(?)", "backlog").first ||
#project.versions.open.where(:effective_date => nil).first ||
Version.open.where(:project_id => #project).order("effective_date ASC").first
#current_version = Version.open.
where(:project_id => #project).
where("#{Version.table_name}.id <> ?", #backlog_version).
order("effective_date DEcSC").first
q = (params[:q] || params[:term]).to_s.strip
#scope = (params[:scope] == "all" || #project.nil? ? Issue : #project.issues).open.visible.where(:fixed_version_id => nil).sorted_by_rank
scope = Issue.open.visible.where(:fixed_version_id => nil).where("project_id = ?", ) OR #project.or(:project_id.parent_id => #project)).sorted_by_rank
#scope = Issue.open.visible.where(:project_id => #current_version) #(:project_id => #project || #project.parent_id == :project_id || #project ).sorted_by_rank
if q.present?
if q.match(/^#?(\d+)\z/)
scope = scope.where("(#{Issue.table_name}.id = ?) OR (LOWER(#{Issue.table_name}.subject) LIKE LOWER(?))", $1.to_i, "%#{q}%")
else
scope = scope.where("LOWER(#{Issue.table_name}.subject) LIKE LOWER(?)", "%#{q}%")
end
end
#issue_count = scope.count
#issue_pages = Redmine::Pagination::Paginator.new #issue_count, 20, params['page']
#version_issues = scope.offset(#issue_pages.offset).limit(#issue_pages.per_page).all
end
So, please, could somebody help me? How could I understand, what #project contains? How could I turn query into scope?
Here's working SQL-query (or at least it got rows I need). But I really have no idea how to make this scope varible contains this data?
SELECT * FROM `issues` WHERE `project_id` IN (SELECT `id` FROM `projects` WHERE `parent_id` IS NOT NULL OR `parent_id` IS NULL ) ORDER BY `id` ASC
Well, actually I fixed this thing this way
def find_no_version_issues
q = (params[:q] || params[:term]).to_s.strip
#scope = (params[:scope] == "all" || #project.nil? ? Issue : #project.issues).open.visible.where(:fixed_version_id => nil).sorted_by_rank
#subprojects = #project.descendants.visible.all
#subprojects = #subprojects.to_a.push #project
scope = Issue.open.visible.where(project_id:#subprojects).where(:fixed_version_id => nil).sorted_by_rank
if q.present?
if q.match(/^#?(\d+)\z/)
scope = scope.where("(#{Issue.table_name}.id = ?) OR (LOWER(#{Issue.table_name}.subject) LIKE LOWER(?))", $1.to_i, "%#{q}%")
else
scope = scope.where("LOWER(#{Issue.table_name}.subject) LIKE LOWER(?)", "%#{q}%")
end
end
#issue_count = scope.count
#issue_pages = Redmine::Pagination::Paginator.new #issue_count, 20, params['page']
#version_issues = scope.offset(#issue_pages.offset).limit(#issue_pages.per_page).all
end
Code:
checkin_scope.count(:select => "user_id", :distinct => true)
SQL query
SELECT COUNT(DISTINCT `checkins`.`user_id`) AS count_user_id,
location_id AS location_id
FROM `checkins` INNER JOIN `locations` ON `locations`.`id` = `checkins`.`location_id`
WHERE `checkins`.`business_id` = 452 AND `checkins`.`status` = 'loyalty'
AND `locations`.`status` = 'approved' AND
`checkins`.`location_id` IN (302825, 302838, 302839, 302901)
AND (date(checkins.created_at) between '2014-10-11' and '2014-11-11')
GROUP BY location_id
I need to remove :distinct => true as it has been removed in Rails 4.1.
Ok, I could solve the problem
checkin_scope.count("DISTINCT(checkins.user_id)")
where checkin_scope is a method,
def checkin_scope
cscope = #business.checkins.loyalty_punchh.joins(:location).where(:locations => {:status => "approved"}).group(:location_id)
cscope = cscope.for_location(#location) if #location
if #from && #to
cscope = cscope.where("date(checkins.created_at) between ? and ?",#from.to_date,#to.to_date)
end
cscope
end
I have a table with these columns: CombinationID, IndexID, Value
There is a sql query:
SELECT CombinationID
FROM CombinationIndex
where IndexID <> 4
group by CombinationID
order by sum(case indexid when 1 then -Value else Value end) desc
How could I write this query in c# by linq?
I think this should just about do it for you (it's all off the top of my head so there could be slight syntactical errors):
var results = context
.CombinationIndexes
.Where(i => i.IndexID != 4)
.GroupBy(i => i.CombinationID)
.OrderBy(g => g.Sum(i => i.IndexID == 1 ? -i.Value : i.Value))
.Select(g => g.Key);
models:
class Change < ActiveRecord::Base
attr_accessor :selected_end_index, :selected_start_index, :revision_number
error:
ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'revision_number' in 'where clause': SELECT * FROM `changes` WHERE (kind = 2 && status = -1 && content_id = 2 && revision_number = 0) ORDER BY id DESC
method:
def new_change_requests_for_latest_version
changes = Change.find(:all,
:conditions => ["kind = ? && status = ? && content_id = ? && revision_number = ?",
Change::CHANGE, Change::NEW, self[:id], self.current_version],
:order => "id DESC")
return changes
end
It means there is no column named "revision_number". The reason you can access it in your app is because attr_accessor sets up the field in the in-memory object. But any value assigned to it will not be persisted in the database, nor can you query on it.
I have a query in my rails application,
user_info = Information.where("user_id = ? and department_id NOT IN (?)",user.id, Department.unapproved_departments ).all(:include => [:name, :project]).
Here unapproved_departments contains an array of ids in Department table.
The problem arises when unapproved_departments is a blank array.In those cases "NOT IN"
checks for ids present in the array and entire user_info is returned as a blank array.
So i would like to have all the data with ids other than those in unapproved_departments array or you can say an alternative for NOT IN
Thanx
Theres nothing wrong with NOT IN -- just that you don't want it to fire when there's nothing there.
I suggest:
user_info = Information.where("user_id = ?", user)
unapproved_departments = Department.unapproved_departments
if unapproved_departments.present? # true if not blank or nil
user_info = user_info.where("department_id NOT IN (?)", unaproved_departments)
end
user_info.all(:include => [:name, :project])
As you can see, you can chain the conditions together.
Can't you just have a special case for when unapproved_departments is empty?
if Department.unapproved_departments.empty?
user_info = Information.where("user_id = ?",user.id).all(:include => [:name, :project])
else
user_info = Information.where("user_id = ? and department_id NOT IN (?)",user.id, Department.unapproved_departments ).all(:include => [:name, :project])
end
it will be better if you define better unapproved_departments to retun [nil] instead of []
Oterwhise you can add [0] to your code :
user_info = Information.where("user_id = ? and department_id NOT IN (?)",user.id, (Department.unapproved_departments << 0) ).all(:include => [:name, :project]).
If we concentrate just on the "NOT IN" part:
user_info = Information.where("department_id NOT IN (?)", []).to_sql
# => SELECT `informations`.* from `informations` where department_id not in (NULL)
Which is weird because of null-tests: http://dev.mysql.com/doc/refman/5.0/en/working-with-null.html
What we can do is reverse the test and get the required result:
user_info = Information.where("NOT (department_id IN (?))", []).to_sql
# => SELECT `informations`.* from `informations` where NOT (department_id in (NULL))
It works because in MySQL everything is != NULL (and also < NULL and > NULL at same time!).