35 votes

Faire une inflexion de rails pour les chaînes possessives ?

J'aimerais créer une méthode en plus de la méthode par défaut 'foo'.titlecase qui lui ajouterait correctement la mention "possessif".

La chaîne de caractères est le nom d'un utilisateur (<- je viens d'en faire un juste là !).

Par exemple : "sam" est l'utilisateur <%= user.titlecase.possessive + ' Profile' %> => #Profil de Sam

Il faut juste gérer les cas limites comme :

Profil de Steelers (devrait être le profil de Steelers) Profil de Ross (devrait être le profil de Ross)

31voto

Coderdad Points 515

J'en ai eu besoin aussi et j'ai donc rendu l'implémentation disponible sur github et comme une gemme sur rubygems afin que vous puissiez l'inclure dans votre projet assez facilement.

Dans les rails 3, tout ce que vous faites est

gem "possessive" 

et vous l'aurez.

24voto

Jamie Flournoy Points 14769

Une réécriture mineure du code de BaroqueBobcat, pour les amoureux de Shoulda (et les amoureux de l'opérateur ternaire) :

Initialisateur :

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

class String
  include StringExtensions
end

J'aurais dû spécifier :

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

15voto

BaroqueBobcat Points 6788

Ce que vous voulez est assez trivial à faire, étant donné les classes ouvertes de 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

Vous voudrez probablement placer cette fonction dans un plugin, afin de la séparer du code de votre logique d'entreprise.

$ script/generate plugin Possessiveate

Il suffit ensuite de déposer le code dans le fichier init.rb généré dans le répertoire du plugin. Pratiquement tous les autres fichiers générés ne sont pas nécessaires, mais vous pourriez être intéressé par la structure des fichiers par défaut.

14voto

Rimian Points 7805

Je n'avais pas vraiment envie d'utiliser un Gem, j'ai donc mis en place une combinaison de certaines réponses déjà présentes ici. Mais je me suis réveillé au milieu de la nuit en réalisant que ces exemples étaient incorrects. Qu'en est-il de "who" et "it" ? (L'anglais est difficile !)

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

Et les spécifications :

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

Remarque : ce n'est pas la solution la plus élégante. Mais comme le disait Albert Einstein, l'élégance est pour les tailleurs.

3voto

Chris Points 48

Si vous pensez que la condition utilisée dans toutes ces réponses jusqu'à présent est incorrecte, vous pouvez plutôt vérifier si le mot est déjà au pluriel.

Donc, en utilisant la solution de Jamie Flournoy comme exemple, vous pouvez utiliser self == self.pluralize au lieu de 's' == self[-1, 1] et on obtient ces résultats :

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

"Ross".pluralize est déjà "Rosses", comme on pouvait s'y attendre. Mais "Chris".pluralize ne l'est pas, il faudrait donc ajouter inflection.irregular "Chris", "Chrises" à inflections.rb pour que la forme possessive apparaisse correctement. Et je suppose que vous devez continuellement ajouter des irrégularités pour d'autres mots/noms peu communs pour finir par avoir les bonnes formes possessives.

Encore une fois, si vous pensez qu'il est insuffisant de vérifier si la dernière lettre d'une chaîne de caractères est un s.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X