我的应用处理“机器”。机器有规格,写成许多“规格”。这些规范中的每一个都包含对“Spec_Field”的引用(诸如“权重”,“高度”,“容量”等字段)和值。
Class Machine
has_many :specs
has_many :spec_fields, :through => :specs
Class Spec
belongs_to :machine
belongs_to :spec_field
我想要做的是在每台机器的#show操作中都有一个搜索功能,用户可以检查他想要匹配的规格(“是,长度50是我需要的,容量500是完美,我不关心宽度“),点击”查找类似“,然后找到所有类似规格的机器。
我假设我需要一个搜索模型,类似于以下截屏视频: http://railscasts.com/episodes/111-advanced-search-form-revised?autoplay=true
在机器的#show操作中,我将需要浏览本机的规格,并将它们添加到“搜索”实例中。那么这是否意味着“规范”也需要属于“搜索”?
我无法理解如何在我的案例中组织一切。任何帮助表示赞赏!
机器:
t.string "title"
t.text "description"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "status"
t.integer "category_id"
t.string "manufacturer"
t.string "model"
t.string "serial"
t.string "year"
t.string "location"
规格:
t.integer "machine_id"
t.integer "field_id"
t.text "value"
t.float "base_value"
t.integer "unit_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
规范字段:
t.string "label"
t.integer "base_units"
我添加了一个“With Spec”范围,它使用SQL“IN”和“SELECT”
def self.with_spec(field_id,value)
min_value = value.to_f * 0.8
max_value = value.to_f * 1.2
where("machines.id IN (SELECT machine_id FROM specs WHERE field_id = ? AND value > ? AND value < ?)",field_id,min_value,max_value)
end
答案 0 :(得分:1)
我会建立我称之为“过滤范围”的东西;如果传入带有适当命名键的哈希值,它们将减少结果集。如果传入的内容为nil或空白,则忽略该条件。
然后我定义了一个类搜索方法,它结合了所有过滤搜索,如下所示:
Class Spec
belongs_to :machine
belongs_to :spec_field
# filter scopes
scope :with_machine, lambda{|*term| where('machine_id = ?',term) if term.present? }
scope :with_length, lambda{|*term| where('length = ?',term) if term.present? }
scope :with_capacity, lambda{|*term| where('capacity = ?',term) if term.present? }
scope :with_width, lambda{|*term| where('width = ?',term) if term.present? }
def self.filter_search(options)
with_machine( options[:machine] ).
with_length( options[:length] ).
with_capacity( options[:capacity] ).
with_width( options[:width] )
end
end
现在您只需要构建一个具有适当命名输入的表单:
<%= text_field_tag 'search[machine]', @machine.id %>
<%= text_field_tag 'search[length]' %>
<%= text_field_tag 'search[capacity]' %>
<%= text_field_tag 'search[width]' %>
<%= submit_tag %>
并在控制器上调用它:
@specs = Spec.filter_search(params[:search]).all
另一种方法是设置全文搜索引擎,并以同样的方式构建搜索方法。
答案 1 :(得分:0)
我认为gem meta_search可以帮助您并简化您的代码。