Writing query with new 'where' - ruby-on-rails

I am trying to do a simple query with Rails 3 where clause.
I have the following:
Participant.find(:first, :conditions => ["participants.role = ? AND participants.board_id = ?", "Manager", board.id])
Which works very well. I am trying to rewrite it the Rails 3 way as follows:
Participant.where(:board => board, :role => "Manager")
However this does not work. Is there a way to stipulate first with the where to get the same return as above?

Participant.where(:board_id => board.id, :role => "Manager").first

Related

How to include NOT in Rails query before Rails 4 when it is tied with other parameters?

I'm trying to combine an existing Rails query with a NOT query. I read that Rails 4 supports this well, but I'd like to know how to do it in Rails 3.
#next_question = Answer.where(:topic => subject, :result => session.question_pool, :user_id => current_user.id, 'practicesession_id != ?', params[:session_id]).first
I've tried the above and keep getting an error. The portion that relates to the NOT is the last bit of the query (practicesession_id). Any advice on how to do this?
In rails 3 this will work
#next_question = Answer.where(:topic => subject, :result => session.question_pool, :user_id => current_user.id)
.where(Answer.arel_table[:practicesession_id].not_eq(params[:session_id])).first
#next_question = Answer.where(topic: subject, result: session.question_pool, user_id: current_user)
.where('practicesession_id != ?', params[:session_id]).first
You can chain your wheres together, using AR syntax in some, and SQL strings in others.

ActiveRecord query with conditionals on nested associations

I've got a Person model, who has_many roles, and roles, in turn, belong_to an application. I'd like to query all the roles a person has for a given application. So far I've got:
p = Person.includes(:roles => [:application]).where(:loginid => 'their_loginid', :roles => {:application_id => 1})
Which works, but it's querying based on Person.roles.application_id; instead, I'd like to query based on Person.roles.application.api_key (another property of an application).
I tried:
p = Person.includes(:roles => [:application]).where(:loginid => 'their_loginid', :roles => {:application => {:api_key => 'the_api_key'}})
but I receive the error that:
no such column: application.api_key
leading me to think my usage of ActiveRecord isn't joining the tables together correctly.
Any ideas?
Try this:
p = Person.includes(:roles => [:application]).where(:loginid => 'their_loginid', :role_id => Application.find_by_api_key('api_key').role_ids)
try this
p = Person.joins.includes(:roles => [:application]).where(:loginid => 'their_loginid', :roles => {:application => {:api_key => 'the_api_key'}})
In my case it woks.

Using conditions as a hash for joined tables

I am using Rails 2.3.5 and is wondering if it is possible to rewrite this query using conditions as a hash.
joined_deals = Deal.all :joins => :shops
:conditions => ["shops.name = ?", name]
to something like :conditions => {"shops.name" => name}. Is it possible in Rails 2?
Yes, it is possible in Rails 2.
For more information, refer here:
specifying-conditions-on-the-joined-tables

How to use the 'where' method from 'ActiveRecord::QueryMethods' in order to limit searching?

I am using Ruby on Rails 3 and I would like to limit a search in a where method from ActiveRecord::QueryMethods using something as the following
Users.where(:name => "Test_name", :limit => 10)
Users.where(:name => "Test_name").limit(10)
That is, I would like to query only 10 records. How I can do that?
In the RoR source code there is:
def where(opts, *rest)
relation = clone
relation.where_values += build_where(opts, rest) unless opts.blank?
relation
end
Your second example works:
Users.where(:name => "Test_name").limit(10)
There is a nice list and explanation of all the query methods in this Rails guide: http://guides.rubyonrails.org/active_record_querying.html
I don't think you can do that in where. You can only do
Users.where(:name => "Test_name").limit(10)
or if you insist to use :limit in other selector method:
Users.find(:all, :conditions => ["name = 'Test_name'"], :limit => 10)

Complex filtering based on a many-to-many relationship

In my application, Annotations are considered "accepted" if either:
They have been explicitly marked "accepted" (i.e., their state == 'accepted')
They were last updated by a user who has the "editor" role
My question is how to find all accepted explanations with a single DB query. Basically I'm looking for the database-driven version of
Annotation.all.select do |a|
a.last_updated_by.roles.map(&:name).include?('editor') or a.state == 'accepted'
end
My first attempt was
Annotation.all(:joins => {:last_updated_by => :roles}, :conditions => ['roles.name = ? or annotations.state = ?', 'editor', 'accepted'])
But this returns a bunch of duplicate records (adding a .uniq makes it work though)
Changing :joins to :include works, but this makes the query way too slow
Are the results of your first attempt just wrong or do they only need an ".uniq"?
Have you tried
:include => {:last_updated_by => [:roles]}
instead of the join?
or making two queries
#ids = Editor.all(:conditions => ["role = 'editor'"], :select => ["id"]).map{|e|e.id}
Annotation.all(:conditions => ["last_updated_by in (?) or state = ?", #ids.join(","), "accepted"]
is that any faster?

Resources