I have a ruby variable #object which can have only one object inside it or multiple objects.
How to check that in Rails.
Tried checking with
.length
.size
.count
Michael's answer should work already, but another option is to check if it includes the Enumerable module (should support all "Array"-ish objects, unless they have their own custom implementation):
#object.is_a? Enumerable
# => returns true if Array-ish or false
Examples
# Array
[].is_a? Enumerable
# => true
# Hash
{}.is_a? Enumerable
# => true
# Set
[].to_set.is_a? Enumerable
# => true
# Subclass of any of the above
class MyArr < Array
end
MyArr.new.is_a? Enumerable
# => true
# ActiveRecord::Relation
User.all.is_a? Enumerable
# => true
# String
'somestring'.is_a? Enumerable
# => false
# Integer/Float
123.is_a? Enumerable
# => false
(123.45).is_a? Enumerable
# => false
# Time
Time.now.is_a? Enumerable
# => false
Gotcha
## Rails 4:
ActionController::Parameters.new.is_a? Enumerable
# => true
## Rails 5:
ActionController::Parameters.new.is_a? Enumerable
# => false
# in Rails 5, ActionController::Parameters no longer inherits from Hash
# ActionController::Parameters is the type of the variable `params` in your controllers
# Because practically speaking you can loop over it, so it should still be an "Array"
# Therefore, you might want to use the following instead of `.is_a? Enumerable`
#object.respond_to? :each
# => returns true if Array-ish or false
ActionController::Parameters.new.respond_to? :each
# => true
You can use respond_to? method
#object.respond_to? :size
It returns true if array of objects
Related
Is there a rails function to detect ["", "", ...] (i.e. An array containing only empty string or strings) as empty
My requirement:
[""].foo? => true
["", ""].foo? => true
["lorem"].foo? => false
["", "ipsum"].foo? => false
I tried using array.reject!(&:empty?).blank?. It worked, but this changed my array. I don't want my array to be changed. Please help me find a compact method.
There isn't a single method, but you can use .all?.
["", nil].all?(&:blank?) # => true
["ipsum", ""].all?(&:blank?) # => false
Or you can get the opposite result with .any?.
["", nil].any?(&:present?) # => false
["lorem", ""].any?(&:present?) # => true
OP was asking for a solution for Rails but I came here while looking for a generic Ruby solutions. Since present? and blank? are both Rails extensions the above solution did not work for me (unless I pull in ActiveSupport which I didn't want).
May I instead offer a simpler solution:
[nil, nil].join.empty? # => true
["", nil].join.empty? # => true
["lorem", nil].join.empty? # => false
I have a model wish contains the bellow method called by before_validation :
def set_to_false
self.confirme ||= false
self.deny ||= false
self.favoris ||= false
self.code_valid ||= false
end
When I run my tests, I got the deprecation message
DEPRECATION WARNING: You attempted to assign a value which is not
explicitly true or false to a boolean column. Currently this value
casts to false. This will change to match Ruby's semantics, and will
cast to true in Rails 5. If you would like to maintain the current
behavior, you should explicitly handle the values you would like cast
to false. (called from cast_value at
./Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.2.1/lib/active_record/type/boolean.rb:17)
I understand I have to cast but I couldn't find a simple and smart way to do it. Any help to remove this deprecation would be great.
Here's a simple booleanification trick that I use often, double negation:
before_validation :booleanify
def booleanify
self.confirm = !!confirm
self.deny = !!deny
...
end
In case you are not familiar with this trick, it'll convert all values to their boolean equivalents, according to ruby rules (nil and false become false, everything else becomes true)
'foo' # => "foo"
!'foo' # => false
!!'foo' # => true
!nil # => true
!!nil # => false
I thought this would be easier to find, but I'm quite surprised that it isn't.
How on Earth do I test if a string is a number (including decimals) outside a Model?
e.g.
is_number("1") # true
is_number("1.234") # true
is_number("-1.45") # true
is_number("1.23aw") #false
In PHP, there was is_numeric, but I can't seem to find an equivalent in Ruby (or Rails).
So far, I've read the following answers, and haven't gotten any closer:
Ruby on Rails - Validate a Cost
Ruby/Rails - How can you validate against decimal scale?
invalid decimal becomes 0.0 in rails
You could borrow the idea from the NumericalityValidator Rails uses to validate numbers, it uses the Kernel.Float method:
def numeric?(string)
# `!!` converts parsed number to `true`
!!Kernel.Float(string)
rescue TypeError, ArgumentError
false
end
numeric?('1') # => true
numeric?('1.2') # => true
numeric?('.1') # => true
numeric?('a') # => false
It also handles signs, hex numbers, and numbers written in scientific notation:
numeric?('-10') # => true
numeric?('0xFF') # => true
numeric?('1.2e6') # => true
You could use Regular Expression.
!!("1" =~ /\A[-+]?[0-9]+(\.[0-9]+)?\z/) # true
!!("1.234" =~ /\A[-+]?[0-9]+(\.[0-9]+)?\z/) # true
!!("-1.45" =~ /\A[-+]?[0-9]+(\.[0-9]+)?\z/) # true
!!("1.23aw" =~ /\A[-+]?[0-9]+(\.[0-9]+)?\z/) # false
You can use it like this or make a method in a module or add this in the String class
class String
def is_number?
!!(self =~ /\A[-+]?[0-9]+(\.[0-9]+)?\z/)
end
end
You can use this site to test your expression : Rubular: a Ruby regular expression editor and tester
I can explain much more the expression if needed.
Hope this helps.
I have an array of strings: ["users", "torrents", "comments"]
these strings are the names of my bd tables.
how can I in .each loop connect to these tables and select|insert some data?
Avoid using eval
here is a simple solution using constantize
note: constantize will not allow arbitrary code to evaluated, it will just try to fetch a ruby constant, namely a Class
["users", "torrents", "comments"].each do |table_name|
# "users" => "User"
# or more complex
# "some_models" => "SomeModel"
#
class_name = table_name.singularize.camelize
# "User" => User
model_class = class_name.constantize
# do something with it
model_class.create!(:value => 12345)
end
How to convert a ruby hash object to JSON? So I am trying this example below & it doesn't work?
I was looking at the RubyDoc and obviously Hash object doesn't have a to_json method. But I am reading on blogs that Rails supports active_record.to_json and also supports hash#to_json. I can understand ActiveRecord is a Rails object, but Hash is not native to Rails, it's a pure Ruby object. So in Rails you can do a hash.to_json, but not in pure Ruby??
car = {:make => "bmw", :year => "2003"}
car.to_json
One of the numerous niceties of Ruby is the possibility to extend existing classes with your own methods. That's called "class reopening" or monkey-patching (the meaning of the latter can vary, though).
So, take a look here:
car = {:make => "bmw", :year => "2003"}
# => {:make=>"bmw", :year=>"2003"}
car.to_json
# NoMethodError: undefined method `to_json' for {:make=>"bmw", :year=>"2003"}:Hash
# from (irb):11
# from /usr/bin/irb:12:in `<main>'
require 'json'
# => true
car.to_json
# => "{"make":"bmw","year":"2003"}"
As you can see, requiring json has magically brought method to_json to our Hash.
require 'json/ext' # to use the C based extension instead of json/pure
puts {hash: 123}.to_json
You can also use JSON.generate:
require 'json'
JSON.generate({ foo: "bar" })
=> "{\"foo\":\"bar\"}"
Or its alias, JSON.unparse:
require 'json'
JSON.unparse({ foo: "bar" })
=> "{\"foo\":\"bar\"}"
Add the following line on the top of your file
require 'json'
Then you can use:
car = {:make => "bmw", :year => "2003"}
car.to_json
Alternatively, you can use:
JSON.generate({:make => "bmw", :year => "2003"})