Frage

Ich habe ein Benutzermodell mit Attributen ‚ersten‘ und ‚letzten‘ So zum Beispiel, User.first.first # => "Charlie" User.first.last # => "Brown"

Dieser User-Modell hat auch ein virtuelles Attribut 'full_name'

#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

So zum Beispiel:

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"

Es wäre so schön, wenn ich von diesem virtuellen Attribute suchen könnte so zum Beispiel für die dynamische Entdeckung:

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

Beispiel für die Bedingungen in:

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

Ich bin die Hoffnung, zumindest einige Möglichkeiten, in SQL-Sprache zu finden, die dies tun können; wenn es ein dynamisches virtuelles Attribut ist zu finden, auch, ist, dass zusätzliche Vanille-Quelle auf dem Strudel. (Jemand dies in diesem Winter zu haben?)

Ich war auch besorgt über einen Namen gesucht wird, zum Beispiel „Holmes“ kann nur in der ‚ersten‘ Spalte gesucht werden, aber nicht die ‚letzten‘ abgerufen wird, beispielsweise User.first.full_name #=> "Sherlock Holmes".

Ich habe versucht eine umfassendere Suche zu tun:

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

Zum Beispiel

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"]

Aber ich dachte nur, dass die find_by_full_name Methode hier etwas unhandlich ist.

Ich meine, wenn ich eine Spalte full_name habe, die jedes Mal von einem nach dem concat der ersten und letzten speichern Filter eingestellt wird. Also den Namen einer Person zu finden, vor allem mit Fuzzy-Erinnerung an diese Person, ist hilfreich. Also, wenn ich entweder die ‚Doe‘ erinnerte in dieser Person Vor- oder Nachnamen, kann ich immer tun, eine einfache User.find_by_full_name ( ‚Doe‘), so viele wie möglich wieder weiter es festzunageln.

Und da es sich um eine Spalte ist, kann ich es in einem Fund suchen (: Bedingungen [...]) Klausel, wenn ich so etwas wie Project.find(:all,:include => :users, :conditions=>['users.full_name LIKE ?', query]) zu tun wobei

#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

Happy Holidays N

War es hilfreich?

Lösung

Sie können eine named_scope in Ihrem user.rb verwendet:

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

Dann können Sie tun User.find_by_full_name('John Carver')

Neuigkeiten in Reaktion auf Änderungen der Anforderung

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

Andere Tipps

fand ich Jims Antwort auch hilfreich. Vielen Dank. Ich würde allerdings eine leichte Veränderung machen. Dieser Strom Code führt Sie Mittelnamen zu verlieren. Was ich unten haben ein bisschen chaotisch, aber bewahrt Mittelnamen und Verbindung Nachnamen (man denke an Jean-Claude van Damme). Alles nach dem Vornamen geht im last_name-Feld.

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(' ')}
   }
}

Natürlich kann jeder sauberer Weg, dies zu tun, ist willkommen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top