Rails 4.1 enum query - ruby-on-rails

I am seeing Rails generate the wrong query value when I use an enum col value in a where clause, like this (self added for clarity). dominant_product_strategy is an enum.
def some_model_method_on_myModel
MyModel.where(dominant_product_strategy: self.dominant_product_strategy)
end
This produces the correct value (again, self just added for clarity):
MyModel.where(dominant_product_strategy: self.attributes["dominant_product_strategy"])
I'm guessing that Rails sees the enum as a string, and then converts to a integer value of zero. Ughhhhh!
Am I missing something?
This also works:
MyModelwhere(dominant_product_strategy: MyModel.dominant_product_strategies[dominant_product_strategy])

It seems to be that you have answered your question by yoursef. Enum variables is a hash:
{str1: int1, str2: int2, ...}
The value (integer) is storing in DB, and the string is just representation of the int value. When you call self.dominant_product_strategy, you get the representation (string) of dominant_product_strategy column storing as integer in DB.
I think that your first working solution (self.attributes["dominant_product_strategy"]) is fine.

Related

Erlang: getting record field values

I would like to know if there's an internal function in Erlang, similar to the one posted below, that will give me the record field values instead of the record field names.
record_info(fields, RecordName).
A record in Erlang is really a tuple with it's first element being the name of the record. After compilation is done, the record will be seen as a tuple.
If you have this record definition:
-record(name, [field, anotherfield]).
Then you can define a value of that record type like so:
#name{ field = value1, anotherfield = value2 }.
However, the actual representation for this under the hood is this:
{name, value1, value2}.
Note that the field names are actually gone here.
Now, if you want a list of the values for each field in the record, you can use tuple_to_list:
[name, value1, value2] = tuple_to_list(Record).
So, as jj1bdx pointed out, if you want a ; separated string of all the values, you could do something like this:
string:join([lists:flatten(io_lib:format("~p", [T])) || T <- tl(tuple_to_list(Record))], ";").
This last code snippet is stolen directly from jj1bdx.
Record in record_info(fields, Record) -> [Field] cannot be a variable, because it must be fixed at the compile time.
If you need to handle the elements in a key-value structure dynamically, use maps.

Rails Amounts in Thousands Are Truncated

In my Rails 5 app, I read in a feed for products. In the JSON, when the price is over $1,000, it the JSON has a comma, like 1,000.
My code seems to be truncating it, so it's storing as 1 instead of 1,000.
All other fields are storing correctly. Can someone please tell me what I'm doing wrong?
In this example, the reg_price saves as 2, instead of 2590.
json sample (for reg_price field):
[
{
"reg_price": "2,590"
}
]
schema
create_table "products", force: :cascade do |t|
t.decimal "reg_price", precision: 10, scale: 2
end
model
response = open_url(url_string).to_s
products = JSON.parse(response)
products.each do |product|
product = Product.new(
reg_price: item['reg_price']
)
product.save
end
You are not doing anything wrong. Decimals don't work with comma separator. I'm not sure there is a nice way to fix the thing. But as an option you could define a virtual attribute:
def reg_price=(reg_price)
self[:reg_price] = reg_price.gsub(',', '')
end
The reason this is happening has nothing to do with Rails.
JSON is a pretty simple document structure and doesn't have any support for number separators. The values in your JSON document are strings.
When you receive a String as input and you want to store it as an Integer, you need to cast it to the appropriate type.
Ruby has built in support for this, and Rails is using it: "1".to_s #=> 1
The particular heuristic Ruby uses to convert a string to an integer is to take any number up to a non-numerical character and cast it as an integer. Commas are non-numeric, at least by default, in Ruby.
The solution is to convert the string value in your JSON to an integer using another method. You can do this any of these ways:
Cast the string to an integer before sending it to your ActiveRecord model.
Alter the string in such a way that the default Ruby casting will cast the string into the expected value.
Use a custom caster to handle the casting for this particular attribute (inside of ActiveRecord and ActiveModel).
The solution proposed by #Danil follows #2 above, and it has some shortcomings (as #tadman pointed out).
A more robust way of handling this without getting down in the mud is to use a library like Delocalize, which will automatically handle numeric string parsing and casting with consideration for separators used by the active locale. See this excellent answer by Benoit Garret for more information.

Integer store value is negative

I have a Core Data model that contains an id field which is a Integer 16.
I noticed that the app was saving some object with a negative value in that field
For instance (from sqlite3 command line):
2|1|1|-32223||9|424968994|424968994|step`
I thought I'd switch to Integer 32 in order to fix it but the problem still remains. Object are still saved with a negative value in that field. I'm not quite sure why.
Was that right to switch to Integer 32? Should have this fixed the problem?
Edit: Example of value I want to save
For example the value I am storing is 33239 but it's saved as -32297
Being unsigned long compatible with Integer32 and Integer64, you should pass this type of var (unsigned long) to save in CoreData.
I have a similar issue.I am storing the 33675 integer value in CoreData but when i retrieve i got value like -26532.
In My case i defined my integer value as type int16 so range of int16 is -32,768 to 32,767 when i change my variable from int16 to int64 its resolved my issue.
for reference :Swift - Data Types

How can I Alias Data in a WebGrid

I have an existing database that I can't change. I have a column of type int that has various numbers that mean something.
This something would be a string. For example, 1="dog", 2="cat", 3="bird". There are a dozen or so integers to deal with.
I'm using ASP.NET MVC 3 with EF 4.1 and have a WebGrid binding to the Model. Is there a way to alias the data for these integers listed in the WebGrid to display the string value that mean something to the user?
Any help on this would be greatly appreciated!
Add an enum to your Model:
public enum foo
{
dog = 1, cat, bird //etc
}
Hopefully, you are using ViewModels. If you are, add a property for the enum:
public foo thing {get;set;}
And set the value of thing based on the integer value you get from the database:
Model m = new Model{number = 3};
m.thing = (foo) m.number;
Or you could create a helper and use that within the format parameter to set a value based on the integer, or you could use JavaScript/jQuery to alter the values from ints to strings once they have been rendered to the browser.

activerecord sum returns a string?

This seems very strange to me, an active record sum returns a string, not a number
basket_items.sum("price")
This seems to make it work, but i thought i may have missed something, as this seems like very strange behaviour.
basket_items.sum("price").to_i
According to the (rails 2.3.9) API:
The value is returned with the same data type of the column, 0 if there’s no row
Could your price column be a string or text?
https://github.com/rails/rails/pull/7439
There was a reason it returned a string - calling to_d on a Fixnum in Ruby 1.8 would give a NoMethodError. This is no longer the case in Ruby 1.9 so it's probably okay to change.
ActiveRecord sum:
Difference:
1) basket_items.sum("price")
It will also sum non integer also and it will return non integer type.
2) basket_items.sum("price").to_i
This above will convert into integer.
# File activerecord/lib/active_record/relation/calculations.rb, line 92
def sum(*args)
if block_given?
self.to_a.sum(*args) {|*block_args| yield(*block_args)}
else
calculate(:sum, *args)
end
end
Calculates the sum of values on a given column. The value is returned with the same data type of the column, 0 if there’s no row.
http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-sum
Github:
https://github.com/rails/rails/blob/f8f4ac91203506c94d547ee0ef530bd60faf97ed/activerecord/lib/active_record/relation/calculations.rb#L92
Also see, Advanced sum() usage in Rails.

Resources