我试图对生成的模型字符串进行搜索,该字符串由has_one关联组成。 我的模特在这里:
Street.rb
class Street < ActiveRecord::Base
has_many :houses
validates :street_type, presence: true
validates :name, presence: true, uniqueness: {:scope => :street_type, :case_sensitive => false }
def text
street_type + " " + name
end
end
House.rb
class House < ActiveRecord::Base
belongs_to :street
has_many :apartments
validates :street_id, presence: true
validates :number, presence: true
def text
street.text + ", " + number
end
end
Apartment.rb
class Apartment < ActiveRecord::Base
belongs_to :house
has_one :street, through => :house
has_many :accounts
validates :house_id, presence: true
validates :number, presence: true, uniqueness: {:scope => :house_id, :case_sensitive => false}
def text
house.text + ", ap. " + number
end
end
Account.rb
class Account < ActiveRecord::Base
belongs_to :appartment
has_one :house, :through => :appartment
belongs_to :resident
validates :appartment_id, presence: true
validates :resident_id, presence: true, uniqueness: {:scope => :appartment_id, :case_sensitive => false}
def text
uniq_id + " (" + appartment.text + ")"
end
end
我必须通过匹配一些地址字符串来搜索所有帐户。我不知道该怎么做。
有人可以帮我理解怎么做吗?
答案 0 :(得分:3)
您正在搜索Account#text
,这在DB中找不到,除非您将其存储在那里(请参阅“针对完整的公寓#文本搜索”),其中(通过代码判断)似乎不是案子。您不能在ActiveRecord查询中使用模型方法的返回值。首先,您需要从搜索字符串中解析街道类型和名称,门牌号和公寓号。
假设您知道街道类型和名称,门牌号码和公寓号码,您应该(减去错误,我实际上没有测试过)能够找到帐户
Account.
joins(:apartment => { :house => :street }).
where('apartment.number' => apt_num,
'apartment.house.number' => house_num,
'apartment.house.street.name' => street_name,
'apartment.house.street.street_type' => street_type)
您的地址信息结构严谨。它可能会也可能不会很好。在不知道任何细节的情况下,我建议您检查结构与全文搜索相结合的结构化或非结构化地址信息(纯文本字段)是否适合您。
有关AR查询的更多信息,请参阅http://guides.rubyonrails.org/active_record_querying.html
如果您不想从生成的公寓文本字段中解析名称和数字,则需要将其存储在db中。您可以通过挂钩before_save
并更新文本字段(将其称为cached_text
)来包含Apartment#text
来完成此操作。
class Apartment < ActiveRecord::Base
before_save :update_cached_text
def update_cached_text
self.cached_text = text
end
end
如果您更改门牌号码或街道名称或类型,当然Apartment#cached_text
当然会不同步。为了保持同步,您需要在每次保存房屋或街道时“重新保存”(请参阅#touch
)所有相关公寓。
现在您可以使用完整的Apartment#text
Account.
joins(:apartment).
where('apartment.cached_text' => text)
或其子串
Account.
joins(:apartment).
where("apartment.cached_text LIKE '%?%'", text)
答案 1 :(得分:1)
尝试使用以下
Account.includes([:appartment => [:house => :street]]).where("CONCAT('accounts.uniq_id', ' (', 'streets.street_type', ' ', 'streets.name', ' ', 'houses.number', ', ap. ', 'houses.number', ')') like '%?%'", your_search_text)
答案 2 :(得分:1)
your_result = Account.includes(:apartment, :apartment => :house, :apartment => {:house => :street}).where(:apartment => {:number => ...}).where(:house => {:number => ...}).where(:street => {:name => ...})