0

次のエラーがあります:

no such column: company_name: SELECT count("contact_emails".id) AS count_id FROM "contact_emails" 

モデルContactEmailには、company_name列がありません。仮想属性として作成しました。

その情報に基づいて選択することはできませんか?では、どうすればいいですか?

ContactEmailbelongs_to会社に属する連絡先。

4

1 に答える 1

0

クラス定義に追加されたがデータベースに存在しない仮想属性は、仮想属性がデータベースに存在しないため、データベース選択に使用できません。

データベースを使用して目的の行のスーパーセットを選択してから、仮想属性を使用するRailsレベルで2回目の選択を行うことができます。

例えば

# model Citizen class file
# model fields:
#   id
#   name
#   age
#   city

def can_vote?  # a virtual attribute
   age >= 18 
end

def self.find_voters_by_city(city)  # class level finder
   # returns array of voters in a city
   citizens = Citizen.find_by_city(city) # First select done in database
   citizens.select{|citizen| citizen.can_vote?} # Second select is done at Rails
                                                # level using the Array#select
                                                # method
end

上記は正常に機能しますが、パフォーマンスの問題には十分注意する必要があることに注意してください。Railsレベルでの選択は、dbmsでの選択よりもはるかに遅くなります。また、Rails / DBMS接続を介して、他の方法で必要とされるよりもはるかに多くのデータを転送しています。

定期的に何かを選択する場合は、通常、仮想属性をデータベースにプッシュすることをお勧めします。これをデータベース内の実際の属性にします。

テーブルを変更できない場合は、has_one関係を持つ2番目のテーブルを作成することもできます。2番目のテーブルは、追加の属性を保持します。

追加:2つのテーブルを使用してデータベースで選択

### model Contact
#   id
#   name
#   city
has_one :company
def company_name; company.name; end # a virtual attribute

### model Company
#   id
#   contact_id
#   name
#   employee_count
belongs_to :contact

### Selecting on city (from Contact) and employee_count (from Company)
city = xyz # the city we are searching for
employee_count = 123 # minimum company size we want
contacts = Contact.find(:all, 
      :conditions => ["contacts.city = ? and companies.employee_count >= ?",
         city, employee_count],
      :include => :company)

# above statement does the join and select in the database
# There are also techniques involving named scopes for the above
# And in Rails 3, it will be different too.
于 2010-08-18T01:07:20.177 に答える