Pesquisa de atributo virtual do Rails ou pesquisa de coluna combinada sql
Eu tenho um modelo de usuário com os atributos 'primeiro' e 'último' Então, por exemplo User.first.first # => "Charlie" User.first.last # => "Brown"
Este modelo de usuário também possui um atributo virtual '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
Então, por exemplo:
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"
Seria legal se eu pudesse pesquisar por esse atributo virtual, por exemplo, para encontrar dinamicamente:
User.find_by_full_name('Home Simpson') # this doesn't work
Exemplo para condições em encontrar:
User.all(:conditions => ['full_name LIKE ?', query]) #this doesn't work
Espero encontrar pelo menos algumas maneiras na linguagem SQL que possam fazer isso; se houver um atributo virtual dinâmico, também é uma fonte extra de baunilha no strudel. (alguém tendo isso neste inverno?)
Também estava preocupado com o fato de um nome ser pesquisado. Por exemplo, "Holmes" só pode ser pesquisado na "primeira" coluna, mas não no "último" a ser recuperado, por exemplo,User.first.full_name #=> "Sherlock Holmes"
.
Eu tentei fazer uma pesquisa mais abrangente:
user.rbdef 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
Por exemplo
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"]
Mas eu apenas pensei que o método find_by_full_name aqui é um pouco pesado.
Quer dizer, se eu tivesse uma coluna full_name que fosse definida a cada vez por um filtro depois de salvar com a concat de primeiro e último. Portanto, encontrar o nome de uma pessoa, especialmente com a lembrança difusa dessa pessoa, é útil. Então, se eu me lembrei de "Doe" no primeiro ou último nome da pessoa, sempre posso fazer um simples User.find_by_full_name ('Doe') para retornar o máximo possível para delimitá-lo.
E como é uma coluna, eu posso pesquisar em uma cláusula find (: [...] conditions) se eu tiver que fazer algo comoProject.find(:all,:include => :users, :conditions=>['users.full_name LIKE ?', query])
Onde
#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
Boas festas N