11

'first' および 'last' 属性を持つユーザー モデルがあるので、たとえば User.first.first #=> "Charlie" User.first.last #=> "Brown"

この User モデルには、仮想属性 '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

たとえば、次のようになります。

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"

たとえば、動的検索の場合、その仮想属性で検索できればとてもいいでしょう。

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

検索条件の例:

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

これを行うことができるSQL言語で少なくともいくつかの方法を見つけたいと思っています。動的仮想属性も見つかった場合、それはシュトルーデルの追加のバニラ ソースです。(この冬持ってる人いますか?)

また、検索される名前についても懸念していました。たとえば、「ホームズ」は「最初」の列でのみ検索され、「最後」の列では検索されない可能性がありますUser.first.full_name #=> "Sherlock Holmes"

私はより包括的な検索を試みました:

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

例えば

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

しかし、ここでの find_by_full_name メソッドは少し扱いに​​くいと思いました。

つまり、最初と最後を連結した保存後のフィルタによって毎回設定される列 full_name があったとします。そのため、特にあいまいな記憶を持つ人の名前を見つけることは役に立ちます。したがって、その人の姓または名のいずれかで「Doe」を覚えていた場合、単純な User.find_by_full_name('Doe') をいつでも実行して、できるだけ多くの名前を返し、それをさらに突き止めることができます。

Project.find(:all,:include => :users, :conditions=>['users.full_name LIKE ?', query]) これは列なので、 whereのようなことをしなければならない場合は、find(:conditions[...]) 句で検索できます。

#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

ハッピーホリデーN

4

2 に答える 2

11

user.rb で named_scope を使用できます。

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

それからあなたはすることができますUser.find_by_full_name('John Carver')

要件の変化に対応する新しいもの

named_scope :find_by_full_name, lambda {|full_name| 
  {:conditions => ["first LIKE '%?%' or last LIKE '%?%'", 
    full_name.split(' ').first, full_name.split(' ').last]}}
于 2009-11-27T02:39:47.210 に答える
0

ジムの答えも役に立ちました。ありがとう。少し変更しますが。この現在のコードでは、ミドル ネームが失われます。私が以下に持っているものは少し乱雑ですが、ミドルネームと複合姓を保持しています (Jean-Claude van Damme を考えてみてください)。名の後のすべてが 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(' ')}
   }
}

もちろん、これを行うためのよりクリーンな方法は大歓迎です。

于 2011-01-10T06:17:51.557 に答える