Why `where` method doesn't work, unlike `find`? [duplicate] - ruby-on-rails

This question already has answers here:
Rails .where vs .find
(3 answers)
Closed 2 years ago.
Faced a problem completely incomprehensible to me.
I am getting an error when using the method where.
#winner = Team.where(id: params[:winner_id])
#winner.update(rating: #winner.rating += 20)
undefined method `rating' for #<Team::ActiveRecord_Relation:0x00007faed9018490>
However, if I change #winner = Team.where(id: params[:winner_id]) to #winner = Team.find(params[:winner_id])it will work.
Why where method doesn't work?

Because where always gives you an ActiveRecord_Relation, not a single object. In your case you're filtering on the id, so if that's the primary key, as I suppose, you only get one record, but that's into a relation anyway, because that's the semantic of where.
#winner = Team.where(id: params[:winner_id]).first
or
#winner = Team.find_by(id: params[:winner_id])
One of these should do the trick
where works this way because you could even filter for some not so restrictive columns and get many rows in returns, so you always get a collection of rows. For example, think about this
#people = Person.where(age: 20)
this query retrieves all the people 20 years old. That could get zero, one or many rows but you always get a relation, for sure.

Related

Record not always found

Consider the following
# setup an array of the question ids so far
questions_array = []
questions_array.push(session[:questions_array])
# take a random question whom id is not included in the session[:questions_array]
#question = Question.offset(rand(Question.count)).where('id NOT IN (?)',questions_array).take
# push id to array and later on assign the new array to the session
questions_array.push(#question.id)
session[:questions_array] = questions_array
I have two questions database. One of the two gets returned the other one gives me the error
NoMethodError (undefined method 'id' for nil:NilClass):
this line gives the error questions_array.push(#question.id)
this does not happen everytime! and that is what's strange!
This is how, you can solve it though:
Question
.where.not(id: questions_array)
.order('random()')
.first
But if the questions table get say more than 10,000 records for example, it will be slow. Then you could write recursive procedure, which will pick a random record and check some condition. if condition matches, returns the record, or recursion will go on with some base condition to break in worst case.
My bad seems that the problem lies in the fact that i first get a random id and then check if that id is not in the array which is not what i wanted. So if the random id was included in the array it would give an error as there is none to take.
this is the new line of code.
#question = Question.where('id NOT IN (?)',questions_array).first

rails find records containing specific word [duplicate]

This question already has answers here:
Rails: How to find_by a field containing a certain string
(5 answers)
Closed 7 years ago.
I'm looking for a way to find all entries in a database containing a specific string. I know it's possible to iterate over every entry and see if a string matches but with a growing database i'd rather not do that. I'm wondering if there is a Rails way of doing it.
something like
Table.where("content containsWord ?", "string")
So a function find all records containing a specific string.
Does anyone know a way to do this?
update
duplicate of Rails: How to find_by a field containing a certain string
You can try this
search_term = "string"
tables = Table.where("tables.content LIKE ?", "%#{search_term}%")
or, if you want to ignore case sensitiveness, then do this
search_term = "string"
tables = Table.where("lower(content) LIKE lower(?)", "%#{search_term}%")
Hope this helps!

How to get column from active record query

1 and #2 both do not work. Active Record drives me nuts because I cam never remember when it returns an object or an array. Neither is working this time.
question = Question.select('id, question, promo_title, promo_code, group_id').where(:group_id => group_id).limit(1)
1
cookies[:question_id] = question['id']
2
cookies[:question_id] = question.id
You need to do
cookies[:question_id] = question[0].id
Your query will give you Question::ActiveRecord_Relation object. In order to get the data, you can use #each to iterate through all the records, and #[] to get any specific from the resultant collection. In your case it is holding only one record, so you can use #[] method with the argument to it as 0.
Now question[0] will give you a Question instance, now you can call the #id method on it as per the regular Rails way.

Rails difference between find_by_column vs where [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Rails “find_all_by” vs “.where”
In this piece of code
I was wondering what the difference between line 1 and 2.
The COLUMN_NAME is either nil, or unique value.
def get_row
id = "someidhere"
1 r = Model.find_by_COLUMN_NAME(id)
2 r = Model.where('COLUMN_NAME = ? ', id).first
if !r.nil?
r
else
nil
end
end
Is 2 more explicit than 1? What are some side effects that I should watch out for? (If id was nil, or searching for non existing id)
I was using find_by_COLUMN_NAME before and I was getting unexpected results.
When the function returns, I am calling r.id.to_s where r should be an instance of Model, however, sometimes I am getting the value 2 from nowhere.
.where methods return an ActiveRecord relation, which means they can be chained with other such methods and scopes, as in Model.where(:user_id => id).published. The dynamic finders (.find_by_name, etc.), return model instances or arrays, which cannot be chained with additional scopes.
Dynamic finders can return an ActiveRecord::RecordNotFound error when the expected record is not found (rather than nil, [], or an empty relation) if used with an exclamation point, e.g. User.find_by_email!('example#email.com)`.
They each have their own uses; it's up to you to decide based on the cases in which your method would be called.

Better Way to Randomize (Ruby/Rails 3) [duplicate]

This question already has answers here:
Rails select random record
(8 answers)
Closed 5 years ago.
I'm currently using:
#users = User.order("RANDOM()").limit(6)
to generate a list of 6 random users - however, this method takes a 1200ms toll on page load times. Is there a faster/more efficient way to call 6 random users?
I ended up using the method described here:
Rails select random record
#ramc - Thank you for your comment. Load times are now much faster :)
Assuming auto increment ids, starting from 0 and that User objects are never deleted, the following should be quite fast:
#users = (0..5).map { User.find(rand * User.count) }
Have you tried using a random offset & limit?
class User < ActiveRecord::Base
def self.random num = 1
num.times.map { offset(rand(count)).limit(1) }
end
end
#users = User.random(6)
I've used something similar to get single random instances from AR. You'd have to make it a bit smarter if you wanted to guarantee unique results.
You could get a random Page of users instead. Consider this pagination call using Kaminari
User.order('created_at').page(rand(User.count)).per(6)
This will fire one count query and one query for the page of 6 Users
You could try using array shuffle instead of using mysql random as it can be slow:
#users = User.all.shuffle[0..5]
After all, a collection of ActiveRecord objects is still just an Array

Resources