0

我有以下错误:

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

模型 ContactEmail 没有 company_name 列。我将它创建为虚拟属性。

不能根据这些信息进行选择吗?那我该怎么办?

ContactEmail belongs_to Contact which belongs_to 公司。

4

1 回答 1

0

添加到类定义但不存在于数据库中的虚拟属性不能用于数据库选择,因为虚拟属性不在数据库中。

您可以使用数据库选择所需行的超集,然后在 Rails 级别进行第二次选择,该选择将使用虚拟属性。

例如

# 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 关系。第二个表将包含附加属性。

补充:使用两个表在数据库中选择

### 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 回答