Check if Rails Database Query Returns Nothing - ruby-on-rails

I'd like to know if a Rails database query returns a row or not (I don't need to know whats in the row, just if a row is returned).
I can do this:
academic_year = AcademicYear.find_by_raw_input(year)
if academic_year
...
end
but if I mistype and do a find_all_by:
academic_year = AcademicYear.find_all_by_raw_input(year)
then an empty array is returned, which causes the if statement to be true.
I know, I should be careful and just avoid the all call, but is there a rails-esque call to see if the return result from any query (all or not) is nil?

As you said, find_by_... will return nil, and find_all_by_... will return []. I think what you're looking for is .blank?.
if !academic_year.blank?
#...
end
In console
> AcademicYear.find_by_raw_input(some_non_existent_year).blank?
=> true
> AcademicYear.find_all_by_raw_input(some_non_existent_year).blank?
=> true

Related

Sort a returned object by its boolean parameters [Ruby]

i think i used the right terminology for what i need, i currently have a database call in my home_controller that is returning a call to my database with all the entries in that table specified, Freelancer.
There is an attribute on these records that has either a true or false value, which is "featured".
I need a way to call a sort method, or some other way, on that object with the true being first and then the false being afterwards, i tried using this code
def index
#freelancers = Freelancer.all
p 'below im outputting featured freelancer i hope'
#freelancers.sort_by { |row| [row.featured ? 0 : 1, row.id]}
p #freelancers
end
But unfortunately this did not work, can anyone advise me on a way to get this to work? Id rather have the sorted object returned as is, rather then assigning it to a new one. Just for future features of adding pagy and a filter by cost.
Use order method
def index
#freelancers = Freelancer.order(featured: :desc)
end

Rails Precision searching the database

I have this to find a DB Entry with the key field the same as the ID params. Now, I get this:
undefined method `confirmed=' for<ActiveRecord::Relation::ActiveRecord_Relation_Email:0x007fd5254c33d8>
And the code:
key = Email.where(:key => params[:id])
if key[1] = nil
#error = true
else
key.confirmed = true
#error = false
end
I was expecting to get a nil if it wasn't in the DB or a Email Object. I was also thinking it could return a hash of Email objects. There should be 0 or 1 DB Entrys. How should I do this correctly? I have no idea what a ActiveRecord::Relation is.
Email.where return multiple records. What you actually want to use is Email.find_by which will allow you to pass a hash of conditions you want the record to match (like how Email.where works), but will return either the first record found, or nil. Your conditional will need to change as a result
You seem to get it completely wrong. Please get acquainted with ActiveRecord documentation.
ActiveRecord::Relation represents query results. Yes, you can update records through it, but this way:
key.update_all(confirmed: true)
which will update confirmed attribute on all records found by the query.
If you want to check whether it has returned at least one record, use:
if key.first
...
To update this one record only:
key.first.confirmed = true
key.first.save
or:
key.update_attribute(:confirmed, true)

NoMethodError for nil object on sort_by, and all objects exist

So I have a bunch of users, who all have user.dj_name attributes. It's a validated necessity on the model, but I'm still being cautious here because I'm running into problems.
I want to get a bunch of users, then order them by their dj_name. Something like this:
#djs = Event.all.map { |e| e.program.user }.sort_by {|x,y| x.dj_name <=> y.dj_name }
where it's pulling all DJs who have Events (shows). It fails with "NoMethodError: undefined method `dj_name' for nil:NilClass"
So I tried:
#djs = Event.all.map { |e| e.program.user }
#djs.compact.sort_by! {|x,y| x.dj_name <=> y.dj_name rescue nil}
And it doesn't sort. Without the "rescue nil" clause, I get the same error.
And if I do a reject! if the object is nil I get nothing.
> #djs.reject! {|d| d.nil? }
=> nil
It seems like none of the objects in the array are nil, the sorting mechanism is giving me errors, and rescuing it just stops the sorting process and returns an unchanged array.
halp?
Use sort!, not sort_by!.
sort_by! passes a single argument into its block. So, when you call .sort_by! {|x,y| ... }, y is always nil.
The purpose of sort_by! is to sort by keys instead of elements. The block gets a single element and must return the element's key to use for sorting.
In this code:
#djs.compact.sort_by! {|x,y| x.dj_name <=> y.dj_name rescue nil}
the block returns nil as a key for every element. As result, no sorting happens.
BTW, I agree with #MurifoX that in this particular case you should you database-provided sorting.
Use the database sort for this kind of task. You can resume your queries by using:
Event.all(:include => {:program => :user}, :order => 'users.dj_name')
Decoupling this query would result in the include method making the join associations on your models and the order creating an ORDER BY on your query.

Where method if condition is false

Does it return empty array or nil if condition is false?
For example:
#result=Result.where(:test_id=>test_id, :user_id => current_user.id).first
if there is no result with such test_id and user_id.
I just don't get, I thought first option, but this returns nil.
Your variable is constructed in two parts, the first part returns an ActiveRecord::Relation (which is essentially an array):
#result_array = Result.where(:test_id=>test_id, :user_id => current_user.id)
> #result_array.class
=> ActiveRecord::Relation
which is empty (shows as []) if there are no results.
The second returns the first item, or (if it's the empty array) nil:
> (1..10).first
=> 1
> [].first
=> nil
#first_or_nil = #result = #result_array.first
I recommend typing these type of commands in the rails console to see what the results.
For your problem you may use like this code.
#result=Result.where(:test_id=>test_id).(:user_id => current_user.id).first
Thy to use #bang with method .first!
For example:
#result=Result.where(:test_id=>test_id, :user_id => current_user.id).first!
It should return the first element whit ruby will meet in table "results".
It should help.
You can also use this simple query...
#result=current_user.results.find_by_test_id(:test_id)

Rails - Always have to check exists, and then value?

I am checking to see if a value in a related table exists quite often in my view, in this case, expenses have approvals. If they have not been submitted, then there is no record of them in the approvals table.
I am ending up with some really awkward code
<% if !expense_item.expense_approval || expense_item.expense_approval.approval_status == 0 %>
Is there a way to do an if statement on a value, without having to check if it exists first? Or some default way to set it nil?
You could do the following in your ExpenseItem model:
delegate :approval_status, :to => :expense_approval, :allow_nil => true
This should allow you to simply do the following:
if expense_item.approval_status == 0
The try method above certainly works, but I like delegation better because I don't have to have .try(...) all over my code.
you can use try method which will return nil if method passed doesn't exist. so you could do something like:
expense_item.expense_approval.try(:approval_status) == 0

Resources