2011-08-11 25 views
1

我已经建立了一个包含多种不同模型的RoR数据库。每个“记录”都有很多标记,并且也通过“cat_id”放入一个类别。我已经构建了所有模型,但我需要过滤帮助。现在我可以从节点树视图中选择一个类别,并显示该类别和子类别中的所有记录。我还可以使用搜索功能(SQL中的LIKE运算符)进行简单的文本搜索。我想添加额外的标签过滤器,以便能够选择类别和标签并显示结果。RoR基于多对多关联进行搜索,如标签

这里是我到目前为止有:

创型号

class AuctionRecord < ActiveRecord::Base 

    #comments 
    has_many :comments, :dependent => :destroy 

    #tags 
    has_many :auction_records_tags 
    has_many :tags, :through => :auction_records_tags 

标签模型

class Tag < ActiveRecord::Base 
    attr_accessible :name 
    has_many :auction_records_tags 
    has_many :auction_records, :through => :auction_records_tags 
end 

AUCTIONS_RECORDS_TAGS模型

class AuctionRecordsTag < ActiveRecord::Base 
    attr_accessible :auction_record_id, :tag_id 

    belongs_to :tag 
    belongs_to :auction_record 

end 

正如你可以看到记录一个nd标签具有多对多的关系,因此可以选择多个标签并返回许多拍卖记录。

record控制器

@auction_records = AuctionRecord.filter(session[:search], @cat_sql).order(sort_column + " " + sort_direction).paginate(:per_page => 20, :page => session[:page]) 

过滤功能

#this is the main search engine 
     def self.filter(search, cat_sql) 

     search_sql = "" 

     if search != "" 
      search_sql = "title LIKE '%#{search}%' OR itemnumber LIKE '%#{search}%' OR buyer LIKE '%#{search}%' OR seller LIKE '%#{search}%'" 
      end 

     if cat_sql != "" && search == "" 
      search_sql = cat_sql 
     end  

     if cat_sql != "" && search != "" 
      search_sql = search_sql + " AND " + cat_sql 
     end 

     if search_sql !=""  
      where(search_sql) 
     else 
      scoped 
     end 

     end 

我手动生成的类SQL语句通过通过所有节点和子节点循环。正如你所看到的,我几乎所有的事情都是“手动”的(不是最好的方式)。某些过滤器也可能不被定义的事实很麻烦(例如类别选择,但没有搜索术语)。我认为所有三个过滤器都可以在一行代码中完成,但我不确定它是如何完成的。也许像tags.auction_records?如果我需要发布表的模式,我也可以这样做,但现在所有的分类和标记都是用整数/ id关系完成的。

预先感谢任何帮助/意见

问候

新增信息#1

节点模型(用于分类/类别)

class Node < ActiveRecord::Base 
    has_many :nodes 
    belongs_to :node 
end 

SCHEMA

create_table "auction_records", :force => true do |t| 
    t.string "title"  
    t.string "categorization" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

create_table "auction_records_tags", :force => true do |t| 
    t.integer "auction_record_id" 
    t.integer "tag_id" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "nodes", :force => true do |t| 
    t.integer "node_id" 
    t.string "text" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "tags", :force => true do |t| 
    t.string "name" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

对于“auction_records”,字段分类包含node_id整数以指向它在树视图上属于哪个节点。如果您点击单个节点(类别),则会出现许多auction_records。 auction_records_tags还创建了auction_records和tags之间的关联。我发现了一些仅适用于一个tag_id的东西,但我必须为多个标签工作。

现在我有这样的代码,它是返回错误“协会命名为‘节点’未找到”

 search_term = session[:search] 
     term = "%#{search_term}%" 
     @auction_records = AuctionRecord.scoped 
     @auction_records = @auction_records.where('title LIKE ?', term).where('description LIKE ?',term) if search_term 
     @auction_records = @auction_records.joins(:nodes).where('node.node_id IN ?', session[:cat_id]) if session[:cat_id] 
      @auction_records = @auction_records.joins(:tags).where('tags.id = ?', session[:tag_ids]) if session[:tag_ids] 
     @auction_records = @auction_records.order(sort_column + " " + sort_direction).paginate(:per_page => 20, :page => session[:page]) 
+0

您正在使用哪种Rails版本? –

+0

Rails 3.0.6谢谢! – user783437

回答

1

请记住,在Rails 3中,你可以做链接查询是误差小于级联容易,最好还是使用通配符来防止SQL注入。您可以重构代码,使其看起来类似于:

def self.filter(search_term, categories, tags) 
    term = "%#{search_term}%" 
    auction_records = AuctionRecord.scoped 
    auction_records = auction_records.where('title LIKE ?', term).where('other_field LIKE ?',term) if search_term 
    auction_records = auction_records.joins(:categories).where('categories.name IN ?', categories) if categories 
    auction_records = auction_records.joins(:tags).where('tags.name IN ?' tags) if tags 
end 
+0

感谢您的帮助,我已将它与search_term完美结合,但类别(节点)和标签仍然存在问题。我编辑了我的OP来添加一些关于模型的更多细节。 – user783437

+0

嘿,我无法看到AuctionRecord和Node模型之间的关系,连接(:类别)将无法正常工作。 –

+0

是的,这是我现在正在处理的一个问题。 AuctionRecord有一个名为“categorization”的字段,它包含节点的id(实际上是父节点)......它拥有“node_id”。我不认为我们可以在这里使用.joins(:nodes),因为该关联不是通过RoR,而是通过单个SQL字段。我也想要显示落入点击节点的子项下的所有拍卖记录。我必须手动循环并执行类似“AuctionRecord。(WHERE categorization ='child_node_id_1'或categorization ='child_node_id_2'”)并通过所有孩子。 – user783437