Relings virtuele kenmerk soek of sql search gekombineer kolom
-
05-07-2019 - |
Vra
Ek het 'n gebruiker model met eienskappe se eerste "en" laaste " So byvoorbeeld User.first.first # => "Charlie" User.first.last # => "Brown"
Hierdie gebruiker model het ook 'n virtuele kenmerk '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 byvoorbeeld:
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"
Dit sal so lekker wees as ek kon soek deur daardie virtuele kenmerk so byvoorbeeld vir 'n dinamiese vonds:
User.find_by_full_name('Home Simpson') # this doesn't work
Voorbeeld vir toestande in vonds:
User.all(:conditions => ['full_name LIKE ?', query]) #this doesn't work
Ek hoop om ten minste 'n paar maniere in SQL taal wat dit kan doen vind; as daar 'n dinamiese virtuele kenmerk vind ook dit is ekstra vanielje bron op die strudel. (Iemand wat hierdie hierdie winter?)
Ek was ook bekommerd oor 'n naam wat deursoek word, bv "Holmes" mag slegs gesoek in die kolom "eers", maar nie die 'laaste' te haal, byvoorbeeld, User.first.full_name #=> "Sherlock Holmes"
.
Ek het probeer om 'n meer omvattende search doen:
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
Byvoorbeeld
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"]
Maar ek het net gedink dat die find_by_full_name metode hier is 'n bietjie lomp.
Ek bedoel, as ek 'n kolom FULL_NAME dat elke keer kry stel deur 'n na spaar filter met die concat van eerste en laaste. So vind n persoon se naam, veral met fuzzy geheue van hierdie persoon, is nuttig. So as ek in daardie persoon se eerste of laaste naam onthou 'Doe, kan ek altyd doen 'n eenvoudige User.find_by_full_name (' Doe ') om terug te keer soveel as moontlik om verdere pen dit neer.
En aangesien dit 'n kolom, ek kan dit soek in 'n vonds (: voorwaardes [...]) klousule as ek iets soos Project.find(:all,:include => :users, :conditions=>['users.full_name LIKE ?', query])
doen
waar
#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
Oplossing
Jy kan 'n named_scope gebruik in jou user.rb:
named_scope :find_by_full_name, lambda {|full_name|
{:conditions => {:first => full_name.split(' ').first,
:last => full_name.split(' ').last}}
}
Dan kan jy doen User.find_by_full_name('John Carver')
nuwe dinge in reaksie op veranderinge in vereiste
named_scope :find_by_full_name, lambda {|full_name|
{:conditions => ["first LIKE '%?%' or last LIKE '%?%'",
full_name.split(' ').first, full_name.split(' ').last]}}
Ander wenke
Ek het gevind dat Jim se antwoord nuttig as well. Dankie. Ek sal 'n effense verandering al maak. Hierdie huidige kode veroorsaak dat jy enige middel name verloor. Wat ek hier onder is 'n bietjie slordig, maar bewaar middel name en saamgestelde laaste name (dink Jean-Claude van Damme). Alles na die eerste naam gaan in die LAST_NAME veld.
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(' ')}
}
}
Natuurlik enige skoner manier om dit te doen, is welkom.