I have 5 tables and they related between. Everythings good, perfectly! But i tried to make script, than if in inquiry table field is_answered = 0, so i find respondents (by respondent_id in question table) and send them letter
BUT
I HAVE MISTAKE!
I have this code:
inquiry = Inquiry.find(:all, :conditions => ["is_answered = 0"])
question = inquiry.question
respondents = Respondent.find(:all, :conditions => ["id = (?)", question.user_id])
respondents.each do |r|
Notifier.deliver_user_notification(inquiry)
end
And when i typing ruby blah.rb i get this error:
undefined method `question' for #<Array:0x7f646c82b568>
What my mistake?
PS - Inquiry table (id, question_id, respondent_id) relationship table between questions and answers.
PSS - Respondent table related with Inquiry.
The problem is that you have more inquiry so the following returns an array.
Inquiry.find(:all, :conditions => ["is_answered = 0"])
Try the following, but be mindful of how many sql queries it does, as there are probably optimisations that can be made:
inquiry = Inquiry.find(:all, :conditions => ["is_answered = 0"])
inquiry.each do |i|
question = i.question
respondents = Respondent.find(:all, :conditions => ["id = (?)", question.user_id])
respondents.each do |r|
Notifier.deliver_user_notification(inquiry)
end
end
Related
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.
I have three models, each connected as such: Groups which has many Students which has many Absences.
Absences has a field called created_on.
I only have a group id and would like to obtain all students with an absence of today.
I have created this method inside my Student model:
# Inside student.rb
def self.absent_today_in_group (group)
#SQLITE
find(:all, :joins => :absences, :conditions => ["STRFTIME('%d', created_on) = ? AND STRFTIME('%m', created_on) = ?", Date.today.day, Date.today.month])
#POSTGRES
#find(:all, :joins => :absences, :conditions => ["EXTRACT(DAY FROM created_on) = ? AND EXTRACT(MONTH FROM created_on) = ?", Date.today.day, Date.today.month])
end
Why would that query not return anything? And how could I then also check for group_id?
What version of rails are you using? You can do this in rails 3:
def self.absent_today_in_group(group)
joins(:absences, :group).where(
'absences.created_on' => (Time.now.beginning_of_day..Time.now.end_of_day),
'groups.id' => group.id
)
end
That would find all users which were absent for today for given group.
Shouldnt this be :where and not :conditions?
a user may belong to several groups.
a user may do a review of each group.
users have been deleted from groups without deleting reviews. this causes errors.
when a user logs in i want to delete user reviews for groups to which they no longer belong.
here is the code which isn't working:
#user = session[:user]
#group = session[:group]
#urevs = UserReview.find(:all, :conditions => ["user_id = ?", #user.id])
unless #urevs.nil?
#urevs.each do |r|
ur = #urevs.id
#rv = Review.find(:first, :conditions => ["id = ?", #urevs.review_id])
#gm = GroupMember.find(:first, :conditions => ["group_id = ? and user_id = ?", #rv.group_id, #user.id])
if #gm.nil?
#dest = UserReview.find(:first, :conditions => ["id = ?", ur])
#dest.destroy
end
end
end
I would prefer not to do a mysql query to remove all such instances.
Thanks.
#user.user_reviews.destroy_all(["user_reviews.group_id NOT IN (?)", GroupMember.where(:user_id => #user.id).all.map(&:group_id)])
This part can be replaced by a more convenient method #user.groups.map(&:id) if you have such method
GroupMember.where(:user_id => #user.id).all.map(&:group_id)
Also feel free to replace destroy_all with delete_all if you don't need to cleanup after the records.
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?
I really suck at Rails' finders besides the most obvious. I always resort to SQL when things get more advanced than
Model.find(:all, :conditions => ['field>? and field<? and id in (select id from table)', 1,2])
I have this method:
def self.get_first_validation_answer(id)
a=find_by_sql("
select answers.*, answers_registrations.answer_text
from answers_registrations left join answers on answers_registrations.answer_id=answers.id
where
(answers_registrations.question_id in (select id from questions where validation_question=true))
and
(sale_registration_id=#{id})
limit 1
").first
a.answer_text || a.text if a
end
Can someone create a find method that gets me what I want?
Regards,
Jacob
class AnswersRegistration < ActiveRecord::Base
has_many :answers
end
id = 123
the_reg = AnswersRegistration.first(
:joins => :answers,
:conditions => '(question_id in (select id from questions where validation_question = true)) and (sale_registration_id = ?)', id)
(untested)
Just use binarylogic's Searchlogic gem if that satisfies your need.
Here you go: http://github.com/binarylogic/searchlogic
Sometimes AR will choke on complicated nested conditions, but in theory you should be able to do this:
AnswersRegistration.first(:conditions => { :question => { :validation_question => true },
:sale_registration_id => id },
:include => :answer)