Почему заголовок Rails добавляет пробел в имя?
Почему titlecase
испортит имя? У меня есть:
John Mark McMillan
и он превращает его в:
>> "john mark McMillan".titlecase
=> "John Mark Mc Millan"
Почему в имени добавляется пробел?
В основном у меня это в моей модели:
before_save :capitalize_name
def capitalize_name
self.artist = self.artist.titlecase
end
Я пытаюсь удостовериться, что все имена являются заголовком в БД, но в ситуациях с именем camelcase это терпит неудачу. Любые идеи, как это исправить?
Ответы
Ответ 1
Вы всегда можете сделать это самостоятельно, если Rails недостаточно хорош:
class String
def another_titlecase
self.split(" ").collect{|word| word[0] = word[0].upcase; word}.join(" ")
end
end
"john mark McMillan".another_titlecase
=> "John Mark McMillan"
Этот метод представляет собой небольшую часть секунды быстрее, чем решение регулярного выражения:
Мое решение:
ruby-1.9.2-p136 :034 > Benchmark.ms do
ruby-1.9.2-p136 :035 > "john mark McMillan".split(" ").collect{|word|word[0] = word[0].upcase; word}.join(" ")
ruby-1.9.2-p136 :036?> end
=> 0.019311904907226562
Регрессивное решение:
ruby-1.9.2-p136 :042 > Benchmark.ms do
ruby-1.9.2-p136 :043 > "john mark McMillan".gsub(/\b\w/) { |w| w.upcase }
ruby-1.9.2-p136 :044?> end
=> 0.04482269287109375
Ответ 2
Если вы хотите, чтобы каждое слово начиналось с капитала:
class String
def titlecase2
self.split(' ').map { |w| w[0] = w[0].upcase; w }.join(' ')
end
end
irb(main):016:0> "john mark McMillan".titlecase2
=> "John Mark McMillan"
Ответ 3
Хм, это странно.. но вы могли бы написать быстрое пользовательское регулярное выражение, чтобы избежать использования этого метода.
class String
def custom_titlecase
self.gsub(/\b\w/) { |w| w.upcase }
end
end
"John Mark McMillan".custom_titlecase # => "John Mark McMillan"
Источник
Ответ 4
Отредактировано (вдохновлено предложением The Tin Man)
Взлом будет:
class String
def titlecase
gsub(/(?:_|\b)(.)/){$1.upcase}
end
end
p "john mark McMillan".titlecase
# => "John Mark McMillan"
Обратите внимание, что строка 'john mark McMillan'
несовместима в капитализации и несколько неожиданна как человеческий ввод, или если она не из человеческого ввода, вы, вероятно, не должны хранить строки таким образом. Строка типа 'john mark mc_millan'
более согласована и, скорее всего, будет отображаться в виде человеческого ввода, если вы определите такое соглашение. Мой ответ также будет обрабатывать эти случаи:
p "john mark mc_millan".titlecase
# => "John Mark McMillan"
Ответ 5
документация для заголовка темы ([выделено мной]]:
Заглавные буквы всех слов и заменяет некоторые символы в строке до создайте красиво выглядящий заголовок. titleize предназначен для создания довольно вывода. Он не используется во внутренних компонентах Rails.
Я только угадываю здесь, но, возможно, это относится к PascalCase как к проблеме - возможно, он думает, что это имя ActiveRecordModelClass
.
Ответ 6
Вы пытаетесь использовать общий метод преобразования внутренних строк Rail в более понятные для человека имена. Он не предназначен для обработки "Mc" и "Mac" и "Van Der" и любого количества других сложных написаний.
Вы можете использовать его в качестве отправной точки, а затем в специальном случае результаты поиска мест, которые он разбивает, и делать некоторые исправления, или вы можете написать свой собственный метод, который включает в себя специальные обложки этих крайних случаев. Мне приходилось делать это несколько раз в разных приложениях на протяжении многих лет.
Ответ 7
Вы также можете столкнуться с именами с двумя прописными буквами, такими как McLaren, McDonald и т.д.
Не тратили время на его улучшение, но вы всегда могли
код
# Rails.root/config/initializers/string.rb
class String
def titleize_name
self.split(" ")
.collect{|word| word[0] = word[0].upcase; word}
.join(" ").gsub(/\b('?[a-z])/) { $1.capitalize }
end
end
<сильные > Примеры
[2] pry(main)> "test name".titleize_name
=> "Test Name"
[3] pry(main)> "test name-name".titleize_name
=> "Test Name-Name"
[4] pry(main)> "test McName-name".titleize_name
=> "Test McName-Name"
Ответ 8
Если вы хотите обработать случай, когда кто-то ввел JOHN CAPSLOCK JOE
, а также другие, я добавил следующее:
class String
def proper_titlecase
if self.titleize.split.length == self.split.length
self.titleize
else
self.split(" ").collect{|word| word[0] = word[0].upcase; word}.join(" ")
end
end
end
Зависит, если вы хотите эту логику вида по методу String;)