Use instance variable in "delete_if" method in ruby on rails - ruby-on-rails

I am using
#registers.delete_if { |r| r.location_id != #location_id && #location_id.present?}
to filter the registers so that only the ones with the chosen location_id are kept, if anything was chosen at least. The thing is that using the #location_id.present? works just fine but checking if the id's are the same doesn't. If I check hardcoded with a number like this: r.location_id != 5 it does work.

Try it like this :
#registers.delete_if { |r| r.location_id != #location_id.to_i && #location_id.present?}
But I think to do it better you should do it like :
#registers.delete_if { |r| r.location_id != #location_id.to_i if #location_id.present?}

Related

Two conditions in a ruby block

I am trying to do something like this:
products = products.select { |product|
product.quantity > 0 || (
product.has_attribute?(:permit_negative_quantity) &&
product.permit_negative_quantity == true)
)
}
I am trying to leave only products association that has positive quantity, or, if the quantity is not positive, has the attribute permit_negative_quantity and it is set totrue.
This block keeps rejecting the products with a negative quantity. Am I missing something in the syntax? Is there a better way to do it?
It seems higher priority of && is causing this, try following:
products = products.select { |product| (product.quantity > 0 || (product.has_attribute?(:permit_negative_quantity) && product.permit_negative_quantity == true)) }
Ok finally i saw what i made wrong.
It was the :trueat the end of the condition which have to be truesince the table column is a boolean.

Rails: Conditional statement with && and ||

I currently have this:
<% if h.ab_template.AB_filterParent == 0 && h.status != 'geo_enabled' %>
What I'd like to do is say whether if h.ab_template.AB_filterParent == 0 || nil. How would I do that?
I tried this but it wasn't working:
<% if (h.ab_template.AB_filterParent == 0 || nil) && h.status != 'geo_enabled' %>
Would love to know what I've mistyped or implemented incorrectly!
Cheers
If you are sure that h.ab_template.AB_filterParent will always be a number (can be wrapped by quotes), then you can try following
<% if h.ab_template.AB_filterParent.to_i == 0 && h.status != 'geo_enabled' %>
else, if there is a possibility that h.ab_template.AB_filterParent can be something like "abc", "0asd" etc then try:
<% if (h.ab_template.AB_filterParent.nil? || h.ab_template.AB_filterParent == 0) && h.status != 'geo_enabled' %>
Generally nil and zero shouldn't mean the same thing. Try to eliminate the possibility of AB_filterParent being nil before you hit this code, by assigning a default value of zero in your migration table. I don't know how your model is so I can't even show an example of how to do it.
The main problem of using to_i == 0 is that it only works if AB_filterParent is either an integer or nil.
0.5.to_i == 0
"asdasd".to_i == 0
So it's odd.
Another way is to have it initialized in an action or other model method or even after_create callback.

Check if not nil and not empty in Rails shortcut?

I have a show page for my Users and each attribute should only be visible on that page, if it is not nil and not an empty string. Below I have my controller and it is quite annoying having to write the same line of code #user.city != nil && #user.city != "" for every variable. I am not too familiar with creating my own methods, but can I somehow create a shortcut to do something like this: #city = check_attr(#user.city)? Or is there a better way to shorten this procedure?
users_controller.rb
def show
#city = #user.city != nil && #user.city != ""
#state = #user.state != nil && #user.state != ""
#bio = #user.bio != nil && #user.bio != ""
#contact = #user.contact != nil && #user.contact != ""
#twitter = #user.twitter != nil && #user.twitter != ""
#mail = #user.mail != nil && #user.mail != ""
end
There's a method that does this for you:
def show
#city = #user.city.present?
end
The present? method tests for not-nil plus has content. Empty strings, strings consisting of spaces or tabs, are considered not present.
Since this pattern is so common there's even a shortcut in ActiveRecord:
def show
#city = #user.city?
end
This is roughly equivalent.
As a note, testing vs nil is almost always redundant. There are only two logically false values in Ruby: nil and false. Unless it's possible for a variable to be literal false, this would be sufficient:
if (variable)
# ...
end
This is preferable to the usual if (!variable.nil?) or if (variable != nil) stuff that shows up occasionally. Ruby tends to wards a more reductionist type of expression.
One reason you'd want to compare vs. nil is if you have a tri-state variable that can be true, false or nil and you need to distinguish between the last two states.
You can use .present? which comes included with ActiveSupport.
#city = #user.city.present?
# etc ...
You could even write it like this
def show
%w(city state bio contact twitter mail).each do |attr|
instance_variable_set "##{attr}", #user[attr].present?
end
end
It's worth noting that if you want to test if something is blank, you can use .blank? (this is the opposite of .present?)
Also, don't use foo == nil. Use foo.nil? instead.

syntax error in simple LINQ statement

I am developing MVC app and I am using the LINQ in controller.
I am trying to get one rechord with below query, but its giving an error...
Approval oAP = new Approval();
oAP = db.Approvals.Where(e => (e.ApprovedBy.Id == loggedEmployee.Id) && (e.ReviewNo == oPaymentAdvice.ReviewCount));
Is there any wrong syntax ?
Got the answer
oAP = db.Approvals.Where(e => (e.ApprovedBy.Id == loggedEmployee.Id) && (e.ReviewNo == oPaymentAdvice.ReviewCount)).FirstOrDefault();
Change this
e.ApprovedBy.Id = loggedEmployee.Id
For
e.ApprovedBy.Id == loggedEmployee.Id
You're comparing not assigning values.
Also you may add this
oAP = db.Approvals.Where(e => (e.ApprovedBy.Id == loggedEmployee.Id) && (e.ReviewNo == oPaymentAdvice.ReviewCount)).FirstOrDefault();
Because i'm assuming that you want to return only one
Some remarks:
You should be able to drop the Where:
oAP = db.Approvals.FirstOrDefault(e => (e.ApprovedBy.Id == loggedEmployee.Id) && (e.ReviewNo == oPaymentAdvice.ReviewCount));
Personally, I try to avoid the First and FirstOrDefault functions, because if you know there is only one record and if you want to enforce this, you can use SingleOrDefault:
oAP = db.Approvals.SingleOrDefault(e => (e.ApprovedBy.Id == loggedEmployee.Id) && (e.ReviewNo == oPaymentAdvice.ReviewCount));
If you know there will always be (more than) one record, you can drop the 'OrDefault' part and use First() or Single().

Ruby - Splititng Array after getting data from Mysql

I have the following code to fetch the data from MySQL database into my rails controller
#main = $connection.execute("SELECT * FROM builds WHERE platform_type IS NOT NULL")
This returns a mysql2 type object which behaves like an array i guess.
I want to split this into 2 arrays, first one where platform_type is 'TOTAL' and everything else in the other array.
It actually returns a Mysql2::Result object. Of course you can do
totals = []
others = []
main.each { |r|
(r['platform_type'] == 'TOTAL' ? totals : others) << r
}
but why not use a rails way with smth like:
Builds.where("platform_type = ?", 'TOTAL')
Builds.where("platform_type NOT IN ?", [nil, 'TOTAL'])
Try array.select. Something like
total = #main.select { |build| build.platform_type == 'TOTAL' }
not_total = #main.reject { |build| build.platform_type == 'TOTAL' }
http://matthewcarriere.com/2008/06/23/using-select-reject-collect-inject-and-detect/
Even better, use Enumerable.partition as per this answer: Ruby Select and Reject in one method

Resources