简体   繁体   English

为所有格字符串制作轨道变形?

[英]Making a rails inflection for possessive strings?

I would like to create a method in additional to the default 'foo'.titlecase that will correctly add "possessiveness" to it.我想在默认的 'foo'.titlecase 之外创建一个方法,该方法将正确地向其添加“占有性”。

The string is a user's name (<- just did one right there! )该字符串是用户名(<- 刚刚在那里做了一个!)

For example: "sam" is the user <%= user.titlecase.possessive + ' Profile' %> => #Sam's Profile例如:“sam”是用户 <%= user.titlecase.possessive + 'Profile' %> => #Sam 的个人资料

It just needs to handle edge cases like:它只需要处理边缘情况,例如:

Steelers's Profile ( should be Steelers' Profile) Ross's Profile ( should be Ross' Profile ) Steelers's Profile(应该是Steelers'Profile)Ross's Profile(应该是Ross'Profile)

I needed this too and so I made the implementation available on github and as a gem on rubygems so you can include it in your project pretty easy. 我也需要它,因此我将实现在github上作为rubygems上的宝石提供,因此您可以很容易地将其包含在项目中。

In rails 3 all you do is 在Rails 3中,您所要做的就是

gem "possessive" 

and you will have it. 你会得到的。

A minor rewrite of BaroqueBobcat's code, for Shoulda lovers (and lovers of the ternary operator): 针对Shoulda爱好者(和三元运算符的爱好者)的BaroqueBobcat代码的较小重写:

Initializer: 初始化器:

module StringExtensions
  def possessive
    self + ('s' == self[-1,1] ? "'" : "'s")
  end
end

class String
  include StringExtensions
end

Shoulda spec: 应该的规格:

require File.expand_path(File.dirname(__FILE__) + "/../test_helper")

class StringExtensionsTest < ActiveSupport::TestCase
  context 'String' do
    context '#possessive' do
      should "turn sam into sam's" do
        assert_equal "sam's", "sam".possessive
      end
      should "turn Steelers into Steelers'" do
        assert_equal "Steelers'", "Steelers".possessive
      end
    end
  end
end

Edit: see Rimian's answer to this question, which properly handles "who" and "it". 编辑:请参阅Rimian对这个问题的答案,该答案正确处理了“谁”和“它”。

What you want is pretty trivial to do, given ruby's open classes. 鉴于ruby的公开课,您想要做的事情很简单。

class String
  def possessive
    self + case self[-1,1]#1.8.7 style
    when 's' then "'"
    else "'s"
    end
  end
end


#rspec examples
describe "String#possessive" do
  it "should turn Steelers into Steelers'" do
    "Steelers".possessive.should == "Steelers'"
  end
  it "should turn sam into sam's" do
    "sam".possessive.should == "sam's"
  end
end

You would probably want to put this in a plugin, to keep it separate from your business logic code. 您可能希望将其放在插件中,以使其与业务逻辑代码分开。

$ script/generate plugin Possessiveate

Then just drop the code to the generated init.rb in the plugin's directory. 然后只需将代码拖放到插件目录中生成的init.rb中即可。 Pretty much all the other generated files aren't needed, but you might be interested in looking at the default file structure. 几乎不需要所有其他生成的文件,但是您可能会对查看默认文件结构感兴趣。

I didn't really want to use a Gem so implemented a combination of some answers already here. 我真的不想要使用Gem,因此已经在这里实现了一些答案的组合。 But then I was woken in the middle of the night by the realisation that these examples are incorrect. 但是后来半夜醒来,我意识到这些例子是不正确的。 What about "who" and "it"? 那“谁”和“它”呢? (English is hard!) (英语很难!)

module Possessive
  def possessive
    suffix = if self.downcase == 'it'
      "s"
    elsif self.downcase == 'who'
      'se'
    elsif self.end_with?('s')
      "'"
    else
      "'s"
    end
    self + suffix
  end
end

class String
  include Possessive
end

And the specs: 和规格:

describe Possessive do
  it "has possessive names not ending in s" do
    "james".possessive.should == "james'"
  end

  it "has possessive names not ending in s" do
    "James".possessive.should == "James'"
  end

  it "has possessive names ending in s" do
    "sally".possessive.should == "sally"
  end

  it "has possessive names ending in s" do
    "Sally".possessive.should == "Sally's"
  end

  it "has possessive its" do
    "it".possessive.should == "its"
  end

  it "has possessive Its" do
    "It".possessive.should == "Its"
  end

  it "has possessive who" do
    "who".possessive.should == "whose"
  end

  it "has possessive Who" do
    "Who".possessive.should == "Whose"
  end
end

Note: It's not the most elegant solution. 注意:这不是最优雅的解决方案。 But as Albert Einstein said, elegance is for tailors. 但是正如阿尔伯特·爱因斯坦(Albert Einstein)所说,优雅适合裁缝。

If you think that the condition used in all these answers thus far is incorrect, you can instead check if the word is already pluralized. 如果您认为到目前为止所有这些答案中使用的条件都是错误的,则可以改为检查单词是否已经复数。

So using Jamie Flournoy's solution as an example, you can use self == self.pluralize instead of 's' == self[-1, 1] , and get these results: 因此,以Jamie Flournoy的解决方案为例,可以使用self == self.pluralize代替's' == self[-1, 1] ,并得到以下结果:

"Steelers".possessive # Steelers'
"Ross".possessive # Ross's
"Chris".possessive # Chris' before inflections.rb change, Chris's after

"Ross".pluralize is already "Rosses", as it might be expected. 正如预期的那样, "Ross".pluralize已经是“ Rosses”。 But "Chris".pluralize isn't, so you would have to add inflection.irregular "Chris", "Chrises" to inflections.rb in order for the possessive form to show up properly. 但是"Chris".pluralize不是,因此您必须在inflection.irregular "Chris", "Chrises"中添加inflection.irregular "Chris", "Chrises" ,以使所有格形式正确显示。 And I suppose you may have to continually add irregularities for other uncommon words/names to end up having the right possessive forms. 而且我想您可能不得不为其他不常见的单词/名称不断添加不规则之处,以最终获得正确的所有格形式。

Again this is if you're under the other belief that it's insufficient to check whether the last letter of a string is s. 同样,这是在另一个信念下,即不足以检查字符串的最后一个字母是否为s。

This approach takes advantage of ActiveSupport::Inflector in order to know if a string is singular or plural, which is more accurate in case of irregular or uncountable words.这种方法利用ActiveSupport::Inflector来了解字符串是单数还是复数,这在不规则或不可数的单词的情况下更准确。

In config/initializers/string.rb :config/initializers/string.rb中:

module StringExtensions
  def possessive
    self + (singularize == self ? "'s" : "'")
  end
end

class String
  include StringExtensions
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM