我有以下错误:
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 公司。
我有以下错误:
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 公司。
添加到类定义但不存在于数据库中的虚拟属性不能用于数据库选择,因为虚拟属性不在数据库中。
您可以使用数据库选择所需行的超集,然后在 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.