I would appreciate it if you could answer. Thank you!

I want to achieve

I am creating an app that has a tweet function.
When posting a tweet, we set a validation of 400 characters or less.
However, I want to change the character count according to the characters to be input, as in the following conditions.
・ Double-byte alphanumeric characters and Japanese are treated as 2 characters (when all are entered in Japanese, the maximum number of characters is 200)
・ Half-width alphanumeric characters and line breaks are treated as one character

Current status
validates: content, length: {maximum: 400}
What I tried/investigated (1) # Solved

Line breaks are counted as 2 characters and validation does not work properly
Implemented so that line breaks are counted as one character, referring to.

class Tweet</pre>
<p><br />
I couldn't post when I entered the following on the tweet posting page in the state of.<br />
<strong>It was confirmed that two line breaks were counted.</strong></p>
<pre><code>1234567890 ↵ (↵ = line break)
1234567890 ↵
1234567890 ↵
1234567890 ↵

Therefore, it was implemented as follows.

  validates: content, presence: true, unless:: was_attached?
  validates: content, correct_line_break: {maximum: 50} # change this part

Create a validators directory in the models directory, create a correct_line_break_validator.rb file in it, and enter the following.

class CorrectLineBreakValidator  options [: maximum]

I got the following error statement.

ArgumentError in TweetsController # new
Unknown validator:'CorrectLineBreakValidator'

ThereforePlace correct_line_break_validator.rb directly under the models directory..
The error statement disappeared and I was able to implement it.

What I tried/investigated (2) #Unsolved

Validator that counts 1 full-width character as 2 half-width characters
Implemented by setting the character limit to 3.

validates: content, correct_line_break: {maximum: 3}

Create a length_with_wide_char_validator.rb file in the models directory

class LengthWithWideCharValidator  1? count += 2: count + = 1
class Tweet</pre>
<p><br />
With the above description, enter as follows.</p>
* You cannot post 4 single-byte numbers. (Maximum: 3 can be confirmed to be valid)
* You can post in 3 full-width characters.

From the above, it was confirmed that one full-width character cannot be treated as two half-width characters.

# application_record.rb
require'length_with_wide_char_validator' # Describe this
class ApplicationRecord

I did, but I was able to post even with "3 full-width characters". I want to implement it so that one full-width character can be handled as two half-width characters.

That's it. I would appreciate your advice.

  • Answer # 1

    What is the limitation "I want to change the character count according to the characters I enter" for?
    "For what" ⇐
    Limiting is done to prevent something from happening if you don't do it. What is shown watching?
    When the terms full-width and half-width began to be used (1) "There is only a monospaced font. Full-width takes up twice as much space as half-width" (2) "Half-width is 1 byte, full-width is 2 bytes and doubles the memory" In that era, it was a meaningful limitation, but nowadays when proportionals are normal, (1) is almost meaningless. Can you distinguish between full-width and half-width numbers or by looking at the alphabet pad?
    Now that the memory consumption is UTF-8, it is not doubled but tripled, so it is unclear if it is treated as two characters.
    The size limit of the field in the database is now the number of characters instead of bytes (should)
    It is troublesome that the code and the number of bytes differ depending on the OS, but if it is a Web application, it will be sent again according to the network standard (I think, unconfirmed), so there is no need to take action?
    If the limit is 5 characters and 10 characters, I think that the evaluation difference of 1 byte will be a problem, but 400 characters means "Don't write a big article", so ... ,

    So for me
    "I don't care about that"
    Is recommended.

    If there is actually "for what", please disclose it and if you feel "I see", we will try again.

    Since the last expression of def validate_each is each, the result will always be "not false".
    For example, if value = "1 a", ["1", "a"] will be returned.
    So finallycount<4Let's put it in.

    However, this is not my preference.
    count = value.size + value.gsub (/ [\ t- ~] /,''). size
    Count the number of characters, remove half-width characters, then recount and add.

    \ r \ nIf you want to treatvalue = value.gsub (/ \ r \ n /, "\ n")after.
    [\ t- ~]Is a character from 0x09 to 0x7e. If you input on the screen, only this range will be entered, so I wonder if this is okay.