Question

J'ai un modèle d'utilisateur avec les attributs 'first' et 'last' Donc par exemple User.first.first # = > " Charlie " User.first.last # = > "Brown"

Ce modèle d’utilisateur a également un attribut virtuel 'nom complet'

#user.rb
def full_name
  [first,last].join(' ')
end

def full_name=(name) #don't know what to do with people w/ middle names
  split = name.split(' ')
  self.first = split[0]
  self.last = split[1]
end

Ainsi, par exemple:

User.first.full_name = "Charlie Brown" #=> "Charlie Brown"
User.first.full_name = "Homer Simpson" #=> "Home Simpson"
User.first.save
User.first.first #=> "Homer"
User.first.last #=> "Simpson"

Ce serait tellement bien si je pouvais chercher par cet attribut virtuel Ainsi, par exemple, pour la recherche dynamique:

User.find_by_full_name('Home Simpson') # this doesn't work

Exemple de conditions dans la recherche:

User.all(:conditions => ['full_name LIKE ?', query]) #this doesn't work

J'espère trouver au moins un moyen de le faire en langage SQL; s'il existe également un attribut virtuel dynamique, il s'agit d'une source extra vanilla supplémentaire sur le strudel. (Quelqu'un at-il cela cet hiver?)

J'étais également préoccupé par le nom recherché, par exemple "Holmes". peut uniquement être recherché dans la première colonne, mais pas dans le dernier à extraire, par exemple, User.first.full_name # = > "Sherlock Holmes" .

J'ai essayé de faire une recherche plus complète:

user.rb

def self.find_by_full_name(name) #returns an array of User model
  return all if name.blank?

  split = name.split(' ', 2)
  output = []
  if split.length > 1
    with_scope( :find => { :conditions => ['first LIKE ?', "%#{split[0]}%"] }) do
      output << all(:conditions => ['last LIKE ?', "%#{split[1]}%"])
      output.flatten!
    end
  elsif split.length == 1
    output << all(:conditions => ['first LIKE ?', "%#{split[0]}%"])
    output << all(:conditions => ['last LIKE ?', "%#{split[0]}%"])
    output.flatten!
  end
end

Par exemple

User.find_by_full_name("John").map(&:full_name) #=> ["John Resig", "John Doe"]
User.find_by_full_name("Doe").map(&:full_name) #=> ["John Doe", "Philips Doeringer"]
User.find_by_full_name("John Doe").map(&:full_name) #=> ["John Doe"]

Mais je pensais juste que la méthode find_by_full_name était un peu compliquée.

Je veux dire, si j’avais une colonne nom complet qui est définie à chaque fois par un filtre après sauvegarde avec le concattre premier et dernier. Il est donc utile de trouver le nom d'une personne, en particulier si sa mémoire est floue. Donc, si je me souvenais de 'Doe' dans le prénom ou le nom de cette personne, je pourrais toujours faire un simple User.find_by_full_name ('Doe') pour en renvoyer autant que possible afin de mieux le cerner.

Et comme c'est une colonne, je peux le chercher dans une clause find (: conditions [...]) si je dois faire quelque chose comme Project.find (: all,: include = >: utilisateurs,: conditions = > ['users.full_name LIKE?', requête])

#project.rb
has_many :assignments
has_many :users, :through=>:assignments

#user.rb
has_many :assignments
has_many :projects, :through => :assignments

#assignment.rb
belongs_to :user
belongs_to :project

Joyeuses fêtes N

Était-ce utile?

La solution

Vous pouvez utiliser un named_scope dans votre user.rb:

named_scope :find_by_full_name, lambda {|full_name| 
  {:conditions => {:first => full_name.split(' ').first, 
     :last => full_name.split(' ').last}}
}

Ensuite, vous pouvez faire User.find_by_full_name ('John Carver')

nouveautés en réponse à des modifications d'exigences

named_scope :find_by_full_name, lambda {|full_name| 
  {:conditions => ["first LIKE '%?%' or last LIKE '%?%'", 
    full_name.split(' ').first, full_name.split(' ').last]}}

Autres conseils

J'ai trouvé la réponse de Jim utile également. Merci. Je ferais un léger changement cependant. Ce code actuel vous fait perdre tous les prénoms. Ce que j'ai ci-dessous est un peu brouillon mais conserve les prénoms et les noms de famille composés (pensez à Jean-Claude van Damme). Tout ce qui suit le prénom va dans le champ last_name.

named_scope :find_by_full_name, lambda { |full_name| 
 {:conditions => {:first_name => full_name.split(' ').first, 
   :last_name => full_name.split(' ')[1, full_name.split(' ').length-1].join(' ')}
   }
}

Bien sûr, toute méthode plus propre est la bienvenue.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top