I have a model to handle different application settings. Each setting has a value_type e.g. string, integer, boolean and enum. If a settings is defined as enum, it has many enum_options (just saved as key, value with a reference to the setting in database).
To handle these enums I want to use Enumerize gem. I tried a lot but I can't set enum option from database.
Here is my code how I try to define the different enum options.
enumerize :enum_values, in: -> { EnumOption.where(functional_parameter_id: self.id).map(&:value.to_sym) }
After that I try to call Setting.find(1).enum_values and I got nil.
If I call Setting.enum_values.values to get all available options to select, I just got ["#<Proc:0x007fd7e78e9218#/Users/path/to/app/app/models/setting.rb:31 (lambda)>"]
Is it possible to set the enum options dynamically?
I don't think you can use in with a lamdba literal in enumerize. This feature is not documented anywhere, and having a look at https://github.com/brainspec/enumerize/blob/c65867580967724479af1bffbfbea05cbfa62db4/lib/enumerize/attribute.rb#L15, it seems that enumerize strictly wants you to pass an array.
Related
I have an enum in one of my model in my api
enum pay_method: {
cash: 0,
card: 1
}
I want to have validation for this enum but i can not do that . I wrote a validation in my model for that but it did not take any effect
A validation for enum is not going to work, because Rails does not even allow to assign an enum variable with a wrong value. You will get an error before a validation. There is a good discussion of this behaviour here https://github.com/rails/rails/issues/13971
rails enum functionality throws an error if the value submitted does not correspond to one of the keys or values of the hash. in this case it does not correspond to the key because the value you are submitting is a string so until here you are correct.
the error still appear because enums are set before the validation process. this could help you understand
#shippimg = Shippig.first
#shipping.status = 99
ArgumentError: '99' is not a valid status
rails developers say that programmers are the ones responsible taking care of what values they use assingning to enum attributes
i have made a gem for validating enums inclusion. this at least stops your server from crashing https://github.com/CristiRazvi/enum_attributes_validation
I've an array of objects containing title and salary which is used in typeahead directive.
I display department name and get entire object as value.
If none of the options match, I want user entered string to be converted to object still. Is there any way to update that?
This answer is pretty late, but I would just use ng-blur (to trap the end of the users input) along with a variable bound to typeahead-no-results. Then test if the variable is true in the method bound to ng-blur, and, if so, make an object out of the String supplied by the user and push it to your data source. Simple example found here.
All values coming from a web form are string. I have a class named Announcement which has a field kind and its data type is integer. On the model class I define an enum
enum kind: {
event: 1,
feature: 2
}
About mass assignment I have done it, no problem in general. The problem is when I'm doing this it will complain about '1' is not a valid kind because it's a string not an integer.
announcement=Announcement.new(announcement_params)
Is there any solution for this problem except manually set the value for the field?
Thank you
The answer just come to my mind, this is what i do to solve the problem
kind=params[:announcement][:kind].to_i
params[:announcement].delete(:kind)
params[:announcement].merge(kind: kind)
Get the kind param and convert it to an integer
Remove the kind which is a string from the params
Merge the new kind to the params
And the last is white listing parameters for mass assignment
Thank you #uzaif
You can redefine the setter for the kind attribute in your Announcement model, like this:
# app/models/announcement.rb
def kind=(value)
super(value.to_i)
# or
# super(Integer(value))
end
This converts the given value to integer first and then calls the original method defined by the enum. Note however, that to_i will convert anything, even non-numbers or nils - these will be converted to 0. So I'd advise to either never use 0 among your defined enum values or to use the Integer(value) form, which will raise an exception on non-numbers or nils.
The setter allows mass assignment again:
Announcement.new(kind: '1') # should be OK
I'm using JsonSerializer to convert an Object to a JSON String but the order is wrong. The attributes are automatically sorted alphabetically but I want them in the order they have been listed in the class (e.g. "endPoint" should not appear before "startPoint").
When I call JsonSerializer. I only see 4 methods (toJava or toJson). I tried doing includes with the order but it doesn't work/I'm not doing it right. The way I'm doing it is like this:
return new String[]{"errorDescription", "searchResultRecord.billOfLadingNumber",
"searchResultRecord.bookingNumber", "searchResultRecord.advancedManifest",
"searchResultRecord.inboundCustomsClearanceStatus", "searchResultRecord.cargoReleaseStatus", "searchResultRecord.freightChargeReleaseStatus",
"searchResultRecord.container.containerNumber", "searchResultRecord.container.latestEvent.event",
"searchResultRecord.container.latestEvent.location", "searchResultRecord.container.latestEvent.time"};
As you can see there is obj.obj.attr parts being included. But when I try to run this code I only see "errorDescription" in the output string. I then tried "searchResultRecord" without attributes but it only showed 2 of the attributes in the output :x
Any idea how to fix the order so its not alphabetical? All examples online seem to be from an older version of the class with more accessible methods~ Thanks for any info.
You can try using
#XmlType(propOrder={"startPoint", "endPoint"})
on the class you defined as #XmlRootElement. Those attributes and any other you want will sorted as you defined on propOrder.
I have an object with an attribute called value which is of type big decimal. In the class definition i have validates_numericality_of.
However if i:
a.value = 'fire'
'fire' ends up getting typecast to the correct type before the validation fires so:
a.valid? => true
How do get the validation to fire before the typecast?
Thanks
Dan
From ActiveRecord::Base docs:
Sometimes you want to be able to read
the raw attribute data without having
the column-determined typecast run its
course first. That can be done by
using the <attribute>_before_type_cast
accessors that all attributes have.
For example, if your Account model has
a balance attribute, you can call
account.balance_before_type_cast or
account.id_before_type_cast.
This is especially useful in
validation situations where the user
might supply a string for an integer
field and you want to display the
original string back in an error
message. Accessing the attribute
normally would typecast the string to
0, which isn’t what you want.
A new gem has been created to help validate types in rails.
An explanatory blog post exists to answer more of the "why" it was created in the first place.
With this library your code could be:
class SomeObject < ActiveRecord::Base
validates_type :value, :big_decimal
end
This will throw an exception when anything except a float is assigned to value instead of quietly casting the value to a BigDecimal and saving it.