I'm migrating a project from 2 to 2.3.18. I have a value column(col_type = text) which is serialized.when I store integer also its returning string. May I know what might be the issue.
I'm using mysql database.
ex:
>> a = AppSetting.last
=> #<AppSetting id: 1, name: "kranthi", value: "1", description: nil, created_at: "2013-08-26 12:17:47", updated_at: "2013-08-26 12:17:47">
>> a.value
=> "1"
>> a.value = 1
=> 1
>> a.save!
=> true
>> a = AppSetting.last
=> #<AppSetting id: 1, name: "kranthi", value: "1", description: nil, created_at: "2013-08-26 12:17:47", updated_at: "2013-09-01 14:28:21">
>> a.value
=> "1"
serialize :value
Thanks in advance.
Related
I want to use the new Ruby 3 feature in this very simple case. I know it must be possible but I have not figured it out from the documentation.
Given a hash, I want to check that it has certain keys. I don't mind if it has others in addition. And I want to do this with pattern matching (or know that it is impossible.) I also don't want to use a case statement which seems overkill.
{name: "John", salary: 12000, email: "john#email.com" }
Raise an error if the hash does not have name, and email as strings and salary as a number.
Use the contruct in an if or other conditional?
And what if the hash has strings as keys (which is what I get from JSON.parse) ?
{"name" => "John", "salary" => 12000, "email" => "john#email.com" }
You're looking for the => operator:
h = {name: "John", salary: 12000, email: "john#email.com" }
h => {name: String, salary: Numeric, email: String} # => nil
With an additional pair (test: 0):
h[:test] = 0
h => {name: String, salary: Numeric, email: String} # => nil
Without the :name key:
h.delete :name
h => {name: String, salary: Numeric, email: String} # key not found: :name (NoMatchingPatternKeyError)
With the :name key but the class of its value shouldn't match:
h[:name] = 1
h => {name: String, salary: Numeric, email: String} # String === 1 does not return true (NoMatchingPatternKeyError)
A strict match:
h[:name] = "John"
h => {name: String, salary: Numeric, email: String} # => rest of {:test=>0} is not empty
The in operator returns a boolean value instead of raising an exception:
h = {name: "John", salary: 12000, email: "john#email.com" }
h in {name: String, salary: Numeric, email: String} # => true
h[:name] = 1
h in {name: String, salary: Numeric, email: String} # => false
"I also don't want to use a case statement which seems overkill." case is just the syntax for pattern matching. AFAIK it is not the same as a case when, it's a case in.
h = {name: "John", salary: 12000, email: "john#email.com", other_stuff: [1] }
case h
in {name: String, salary: Integer, email: String}
puts "matched"
else
raise "#{h} not matched"
end
I am using ActiveRecord. It has a handy method called group_by. When I use it with my activerecord objects, i get the below hash:
{["junior"]=>[#<Lead id: 1, created_at: "2015-02-13 02:34:39", updated_at: "2015-02-13 02:35:27", case_enabled: true>, #<Lead id: 2, created_at: "2015-02-13 20:48:19", updated_at: "2015-02-13 20:48:19", case_enabled: nil>, ["senior"]=>[#<Lead id: 3, created_at: "2015-02-13 20:48:19", updated_at: "2015-02-13 20:48:19", case_enabled: nil>, #<Lead id: 4, created_at: "2015-02-13 20:49:16", updated_at: "2015-02-13 20:49:16", case_enabled: nil>]}
However, I want a hash with subhashes that contain the collection as an ActiveRecord::Relation and column data. So this is what I come up with:
i = 0
r = group.reduce({}) do |acc, (k,v)|
h = {}
active_record_relation = where(id: v.map(&:id))
h["#{k.first}_collection"] = active_record_relation
h["#{k.first}_columns"] = Classification.where(code: k.first).first.default_fields
acc[i] = h
i += 1
acc
end
And it gives me the results I want:
{0=>{"junior_collection"=>#<ActiveRecord::Relation [# ... ]>, "junior_columns"=>[ ... ]}, 1=>{"senior_collection"=>#<ActiveRecord::Relation [# ... ]>, "senior_columns"=>[ ... ]}}
The fact that I had to add the i variable makes me feel like this is not the ruby way to do this. But I looked at the docs and I didn't find a way to add an index to reduce, since I am already passing a hash into reduce. Is there another way?
Your way is probably good enough but you can avoid separately tracking the index by doing .each.with_index.reduce(...) { |acc, ((k,v),i)| ... }, like so:
h = {'a' => 'b', 'c' => 'd', 'e' => 'f'}
h.each.with_index.reduce('OK') do |acc, ((k, v), i)|
puts "acc=#{acc}, k=#{k}, v=#{v}, i=#{i}"
acc
end
# acc=OK, k=a, v=b, i=0
# acc=OK, k=c, v=d, i=1
# acc=OK, k=e, v=f, i=2
# => "OK"
Not sure if it's more Rubyish than your way =\
I have an array like this:
arr = [{id: 1, name: 'John' }, {id: 2, name: 'Sam' }, {id: 3, name: 'Bob' }]
I need to check if any of arr objects have name Sam. What is the most elegant way? I can only think of cycling with each.
I need to check if any of arr objects have name Sam
Enumerable#any? is a good way to go.
arr = [ {id: 1, name: 'John' }, {id: 2, name: 'Sam' }, {id: 3, name: 'Bob' }]
arr.any? {|h| h[:name] == "Sam"}
# => true
Now if you also want to see which Array object has the value Sam in it,you can use Enumerable#find for the same:
arr.find {|h| h[:name] == "Sam"}
# => {:id=>2, :name=>"Sam"}
You can also choose select or count methods
Enumberable#select
> arr = [{id: 1, name: 'John' }, {id: 2, name: 'Sam' }, {id: 3, name: 'Bob' }]
> arr.select { | h | h[:name] == 'Sam' }
# => [{:id=>2, :name=>"Sam"}]
Enumberable#count
> arr.count { | h | h[:name] == 'Sam' }
# => 1
You can use Enumberable#find_all to return all object that match the constrain
arr = [{:id=>1,:first_name=>'sam'},{:id=>2,:first_name=>'sam'},{:id=>3,:first_name=>'samanderson'},{:id=>4,:first_name=>'samuel'}]
arr.find_all{|obj| obj.first_name == 'sam'}
# => [{:id=>1,:first_name=>'sam'},{:id=>2,:first_name=>'sam'}]
When I clone a simple object in ruby-1.9.2-p290, everything looks OK
class Klass
attr_accessor :str
end
s1 = Klass.new #=> #<Klass:0x401b3a38>
s1.str = "Hello" #=> "Hello"
s2 = s1.clone #=> #<Klass:0x401b3998 #str="Hello">
s2.str = "Hello world" #=> "Hello world"
s2 #=> #<Klass:0x00000100977c40 #str="Hello world">
s1 #=> #<Klass:0x00000100993fa8 #str="Hello">
But when I clone an ActiveRecord object then something strange happens:
I am using the rails 3.1.8.
Loading development environment (Rails 3.1.8).
When I start the 'rails console'.
ruby-1.9.2-p290 :001 > chair = Chair.new(:code => 'code', :description => 'The Description')
#=> #<Chair id: nil, code: "code", description: "The Description", user_id: nil, created_at: nil, updated_at: nil>
ruby-1.9.2-p290 :002 > chair_clone = chair.clone
#=> #<Chair id: nil, code: "code", description: "The Description", user_id: nil, created_at: nil, updated_at: nil>
ruby-1.9.2-p290 :003 > chair_clone.description = "Update description"
#=> "Update description"
ruby-1.9.2-p290 :004 > chair_clone
#=> #<Chair id: nil, code: "code", description: "Update description", user_id: nil, created_at: nil, updated_at: nil>
ruby-1.9.2-p290 :005 > chair
#=> #<Chair id: nil, code: "code", description: "Update description", user_id: nil, created_at: nil, updated_at: nil>
Isn't it strange that the description attribute of the original object 'chair' is also updated.
I found the following warning in the http://apidock.com/ruby/Object/clone doc
Change in clone for ActiveRecord objects in ruby-1.9.3
I noticed that cloning an active record object in ruby-1.9.3 and then changing an attribute on the original object will actually change the cloned object as well. This was not the case in ruby-1.9.2.
Is there already a solution available for this issue ?
Thanks in advance for any feedback.
Joost
Instead of using clone use dup like:
...
chair_clone = chair.dup
...
u = User.last
u.duplicable? # => true
u2 = u.dup
u2.email = 'wwwww'
u.email # => 'megacoder#rambler.ru'
u2.email # => 'wwwww'
I have an array in my Rails 3.1 apps that has made by several objects:
[#<Hardware id: 10, brand_id: 5, model: "B4200", description: "Stampante OKI B4200", typology_id: 3, sub_typology_id: 10, created_at: nil, updated_at: nil>, #<Hardware id: 19, brand_id: 9, model: "JetLab", description: "JetLab - 600 ", typology_id: 5, sub_typology_id: nil, created_at: nil, updated_at: nil>]
and I want remove one object from this array. Using Rails console, I've tried to do something such as (try to remove first object):
array.pop=#<Hardware id: 10, brand_id: 5, model: "B4200", description: "Stampante OKI B4200", typology_id: 3, sub_typology_id: 10, created_at: nil, updated_at: nil>
but it doesn't work. How can I do this?
UPDATED: My goal isn't to pop last element on array, but a generic object (everywhere inside array) that I should find using mysql search query.
my_array = [ 1, 2, 3 ]
item = my_array.pop
puts item
# => 3
puts my_array
# => [ 1, 2 ]
You probably want to use the Array#delete function
an_array = [1,3,4]
an_array.delete(3)
# => 3
puts an_array
# => [1,4]
Check it out in the Ruby documentation:
http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-delete