2011-08-11 5 views
1

저는 여러 모델로 RoR 데이터베이스를 구축했습니다. 각 "레코드"에는 많은 태그가 붙어 있으며 "cat_id"에 의해 범주에 포함됩니다. 모든 모델을 구축했지만 필터링과 관련하여 도움이 필요합니다. 지금은 노드가있는 트리보기에서 범주를 선택할 수있는 기능이 있으며 해당 범주 및 하위 범주의 모든 레코드가 표시됩니다. 검색 기능 (SQL에서 LIKE 연산자)을 사용하여 간단한 텍스트 검색을 수행 할 수도 있습니다. 범주 및 태그를 선택하고 결과를 표시 할 수 있도록 태그의 추가 필터를 추가하고 싶습니다.RoR 태그와 같은 many to many 연관을 기반으로 검색합니다.

녹화 모델

class AuctionRecord < ActiveRecord::Base 

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

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

TAG의 모델

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 태그는 many to many 관계가 있으므로 많은 태그를 선택하고 많은 경매 레코드와 함께 반환 될 수 있습니다.

RECORD 컨트롤러

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

필터 (Filter) 기능

#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 문을 생성합니다. 당신이 볼 수 있듯이 나는 거의 모든 것을 수동으로 (최선의 방법은 아님)한다. 특정 필터가 정의되지 않을 수도 있다는 사실은 번거로운 작업이었습니다 (예 : 카테고리 선택, 검색어 제외). 모든 세 가지 필터는 한 줄의 코드에서 수행 할 수 있다고 생각하지만 어떻게 완료되었는지는 잘 모르겠습니다. tag.auction_records와 같은 것일까 요? 테이블의 스키마를 게시해야 할 경우이를 수행 할 수도 있지만 현재는 모든 범주화 및 태그 지정이 정수/ID 관계로 수행됩니다. 사전에 어떤 도움

감사합니다/의견

안부

추가 정보 # 1

NODE의 모델

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_tags는 auction_records와 태그 사이의 연관을 생성합니다. 하나의 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

어떤 레일 버전을 사용하고 있습니까? –

+0

Rails 3.0.6 감사합니다! – user783437

답변

1

레일 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에 대한 자세한 내용을 추가하기 위해 OP를 편집했습니다. – user783437

+0

안녕하세요, AuctionRecord와 Node 모델 간의 관계를 볼 수 없기 때문에 조인 (: categories)이 작동하지 않습니다. –

+0

네, 지금 제가하고있는 문제입니다. AuctionRecord에는 노드의 ID (실제로는 부모)가 들어있는 "categorization"이라는 필드가 있습니다.이 노드에는 "node_id"가 있습니다. 우리는 연관이 RoR을 통하지 않고 단일 SQL 필드를 통해 있기 때문에 .joins (: nodes)를 사용할 수 있다고 생각하지 않습니다. 또한 클릭 한 노드의 자식 아래에있는 AuctionRecords를 모두 표시하려고합니다. 수동으로 루프를 돌리고 "AuctionRecord"와 같은 작업을 수행해야했습니다 (카테고리 지정 = 'child_node_id_1'또는 카테고리 = 'child_node_id_2' "). 모든 하위 항목을 거쳐야합니다. – user783437