I have a condition like:
if connection
if "name" == connection.name
...
end
end
connection may have nil value initially, so I am not able to check if connection && "name" == connection.name
How can I simplify the condition efficiently?
if connection and connection.name == "name"
...
end
unless connection.nil? || connection.name != "name"
#...Statements
end
Related
i am trying to write a scope for the model Event
i want to display all events that have expired and have been closed
schema
create_table "events", force: :cascade do |t|
t.string "title"
t.text "description"
t.date "date"
t.boolean "close"
end
event.rb
scope :expired_or_closed_events, -> {where(['close = ? OR close IS ?', true] || ['date < ?', Date.current])}
i tried the above scope but i get the below error
2.3.0 :014 > events.expired_or_closed_events
ActiveRecord::PreparedStatementInvalid: wrong number of bind variables (1 for 2) in: close = ? OR close IS ?
could one kindly advise me how i write the scope for this correctly
Your scope should be:
scope :expired_or_closed, -> { where("close = true OR date < ?", DateTime.now) }
Or using Arel
scope :expired_or_closed, -> { where(arel_table[:close].eq(true).or(arel_table[:date].lt(DateTime.now)) }
Note that I use expired_or_closed not expired_or_closed_events, because we are defining this scope in Event model, using `events' is redundant.
Use This
scope :expired_or_closed_events, -> { where( "close == ? || date < ? ", true, Date.current ) }
I think your condition should be **close == ? **
otherwise no sense of condition, which always calculate as true
row = {"joining_date"=>"18/07/2015", "name"=>" Joe Doe ", "company"=>" Google", "location"=>" New York ", "role"=>"developer", "email"=>"joe#doe.com", "mobile"=>"11-(640)123-45674", "address"=>"4 XYZ Road", "validity"=>"true"}
row is invalid only if any one of the fields(joining_date, name, company, location, email, address) is nil or not present.
def is_valid?
valid = true
if row[:name] == nil || row[:joining_date] == nil || row[:address] == nil || row[:email] == nil || row[:company] == nil || row[:location] == nil
valid = false
end
valid
end
Is there any way that I can simplify and refactor the above method in rails to find it more efficient using regex?
Probably, but I wouldn't use a regex as it's in a hash. As you're using rails you can use present? or blank?.
row.values.any?(&:blank?)
Would return true if any are blank
for your case
def is valid?
row.values.all?(&:present?)
end
Let's say I have a list of records like:
transactions = Transaction.all
And I have the following instance methods #currency, #geo, #industry. I want to select records which has the following criteria:
Select all transactions that has field currency which equals to #currency unless #currency is nil and in this case we'll ignore the condition (currency would mean all currencies when it's nil)
Select all transactions that has field geo which equals to #geo unless #geo is nil.
Select all transactions that has field industry which equals to #industry unless #industry is nil.
I tried multiple #select but with no luck something like:
transactions.select{ |i| (i.currency == #currency) unless #currency.nil? }.
.select{ |i| (i.geo == #geo) unless #geo.nil? }.
.select{ |i| (i.industry == #industry) unless #industry.nil? }
The problem with your example is the unless #currency.nil? will return nil (which is falsey) if #currency is nil, which is the opposite of what you intended.
You should use || instead:
transactions.select{ |i| (i.currency == #currency) || #currency.nil? }.
select{ |i| (i.geo == #geo) || #geo.nil? }.
select{ |i| (i.industry == #industry) || #industry.nil? }
In this case, if #currency is nil, the first condition will return true, and all elements will pass the select box to the next one...
Another option would be to run the select block only is the parameter is not nil. In this case, you'd like to break the line into separate blocks:
transactions.select!{ |i| (i.currency == #currency) } unless #currency.nil?
transactions.select!{ |i| (i.geo == #geo) } unless #geo.nil?
transactions.select!{ |i| (i.industry == #industry) } unless #industry.nil?
transactions.select do |t|
(#currency.nil? || t.currency == #currency) &&
(#geo.nil? || t.geo == #geo) &&
(#industry.nil? || t.industry == #industry)
end
this should do the job.
Or, if you are into dynamics:
[:currency, :geo, :industry].all? do |field|
(ivar = instance_variable_get("##{field}")).nil? || t.send(field) == ivar
end
Use AR/SQL instead of Ruby processing when possible:
transactions.where(currency: #currency, geo: #geo, industry: #industry)
Multiple use of select is superfluous in this situation. You can use && and || logical operators:
transactions.select do |transaction|
(#currency.nil? || transaction.currency == #currency) &&
(#geo.nil? || transaction.geo == #geo) &&
(#industry.nil? || transaction.industry == #industry)
end
I'm looking through my object attributes for culprits that are not :
^[1-3]{3}$
What is the method used to scan integers for regexp?
Some examples:
124.to_s.match(/^[1-3]{3}$/)
=> nil
123.to_s.match(/^[1-3]{3}$/)
=>#<MatchData "123">
Since nil is considered as false, you have your boolean.
Ex:
"no yo" if 124.to_s.match(/^[1-3]{3}$/)
=> nil
"yo!" if 123.to_s.match(/^[1-3]{3}$/)
=> "yo!"
You may use also one of the following:
def is_pure_integer?(i)
i.to_i.to_s == i.to_s
end
or
'132' =~ /^\d+$/ ? true : false
I asked a question earlier which elicited some great responses.
Here's the earlier question
On the back of some advice given there, I've tried moving the following controller logic
if params[:concept][:consulted_legal] == 0 && params[:concept][:consulted_marketing] == 1
#concept.attributes = {:status => 'Awaiting Compliance Approval'}
elsif params[:concept][:consulted_marketing] == 0 && params[:concept][:consulted_legal] == 1
#concept.attributes = {:status => 'Awaiting Marketing Approval'}
elsif params[:concept][:consulted_marketing] == 0 && params[:concept][:consulted_legal] == 0
#concept.attributes = {:status => 'Awaiting Marketing & Legal Approval'}
else
#concept.attributes = {:status => 'Pending Approval'}
end
into the model, as so:
def set_status
if status.blank?
if (consulted_legal == true) && (consulted_marketing == true)
status = "Pending Approval"
elsif (consulted_legal == true) && (consulted_marketing == false)
status = "Awaiting Marketing Approval"
elsif (consulted_legal == false) && (consulted_marketing == true)
status = "Awaiting Legal Approval"
elsif (consulted_legal == false) && (consulted_marketing == false)
status = "Awaiting Marketing & Legal Approval"
end
end
true # Needs to return true for the update to go through
end
I am calling that from a before_save callback.
As a default, both the consulted_legal and consulted_marketing attributes are set to false and not null, which is why I am testing for == false or true here, instead of asking
if consulted_legal?
for instance.
However, this logic doesn't seem to be working. If I inspect the object, status is not being set to anything, ever. Can anyone spot why this might be happening? Have I got how attributes are accessed wrong in models, for instance?
TIA
Instead of status = try self.status =. I've found that I needed to use self. to change a model's attribute within the model.
It's also much better to have errors.empty? at the end instead of true, so if you ever use errors.add_to_base in the future, your set_status method is ready to abort a save.
Edit:
You may also want to check out acts_as_state_machine. It looks like a plugin for exactly what you're doing.
Are you setting the parameters from user input?
If they're not defined as boolean database columns, then you'll be assigning a string to them, which will never be equal to true.