-
-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider using the Attributes API instead of before_validation callbacks #43
Comments
Sounds like a good idea! I saw the discussion in #34 about using setters, I think whatever you'll end up with will be better than I'm not sure how exactly the attributes API works, but it might give the option to use |
Just made my own for this, since the current implementation is doing in place string manipulation, which won't work in ruby 3. I only overwrote cast, since I don't want it to run when loading from the database. On using multiple filters: it's really easy to create a wrapper type, that calls them both. So I would leave that the application. # frozen_string_literal: true
# Strips whitespace and make nil when string becomes empty.
class StrippedString < ActiveModel::Type::ImmutableString
# taken from strip_attributes gem
# Unicode invisible and whitespace characters. The POSIX character class
# [:space:] corresponds to the Unicode class Z ("separator"). We also
# include the following characters from Unicode class C ("control"), which
# are spaces or invisible characters that make no sense at the start or end
# of a string:
# U+180E MONGOLIAN VOWEL SEPARATOR
# U+200B ZERO WIDTH SPACE
# U+200C ZERO WIDTH NON-JOINER
# U+200D ZERO WIDTH JOINER
# U+2060 WORD JOINER
# U+FEFF ZERO WIDTH NO-BREAK SPACE
MULTIBYTE_WHITE = "\u180E\u200B\u200C\u200D\u2060\uFEFF"
MULTIBYTE_SPACE = /[[:space:]#{MULTIBYTE_WHITE}]/.freeze
def initialize(allow_empty: false)
super()
@allow_empty = allow_empty
end
def cast(value)
return unless value
value = super(value).gsub(/\A#{MULTIBYTE_SPACE}+|#{MULTIBYTE_SPACE}+\z/, "").freeze
value.blank? && !@allow_empty ? nil : value
end
end |
Note that in your example you need to either use: class Something < ActiveRecord::Base
attribute :title, Strippable.new(allow_empty: true)
end or add this to an initializer
and use it like this: class Something < ActiveRecord::Base
attribute :title, :stripped_string, allow_empty: true
end |
Are you still interested in this? I'm thinking about it. i (or someone else) could potentially PR... it's potentially fairly simple code; then again, we could also easily copy/paste fork (thanks for MIT license) your logic into an attribute-based thing in another gem, the code here is pretty simple. Some features aren't really available anymore with an ActiveModel-attribute-based implementation. Like the if/unless stuff -- inside attribute casting, you don't have access to the containing record to make decisions based on it's state. And you have a bit more cumbersome API to specify, as you need to write an So... it's got plusses and minuses. Maybe it's really a separate gem. Would you care to update with your current thinking or plans on things? |
Looking forward to this gem using the new |
@justinko "the new normalize Rails method" -- I haven't heard of that, and am not having luck googling for it. This is something built into rails, not a third-party something? Can you give me a link to something? Thanks! |
Whoops, I got the name wrong! |
One major difference is that:
I don't think I would always want that. For example, if normalization is converting the attribute from |
Oh, that is very interesting, thanks @justinko . It does look like a generalized approach to what is being discussed here. @petrgazarov , I see what you mean, but any appraoch based on the Rails Attributes API is probably going to work like this. Because Rails will always |
Related to #34.
Investigate and perhaps consider using the new attributes API instead of a
before_validation
callback.The text was updated successfully, but these errors were encountered: