2012-10-02 186 views
0

我仍然无法搜索存储在单独表中的技术,其中技术表(技术)和Project表之间通过名为projecttechnol的表存在关系。Ruby on Rails:表关系搜索

这是我的日志,当我尝试使用技术(tech1)搜索项目时。

Parameters: {"utf8"=>"✓", "client"=>"", "industry"=>"", "role"=>"", "technols"=>{"id"=>["", "1", ""]}, "business_div"=>"", "project_owner"=>"", "start_date_dd"=>"", "start_date_A"=>"", "start_date_B"=>"", "status"=>"", "keywords"=>"", "per_page"=>"10"} 
    User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1 
    Technol Load (0.3ms) SELECT "technols".* FROM "technols" 
    Project Load (0.5ms) SELECT "projects".* FROM "projects" ORDER BY client 
    Project Load (0.6ms) SELECT "projects".* FROM "projects" ORDER BY industry 
    Project Load (0.4ms) SELECT "projects".* FROM "projects" ORDER BY role 
    Project Load (0.4ms) SELECT "projects".* FROM "projects" ORDER BY tech 
    CACHE (0.0ms) SELECT "projects".* FROM "projects" ORDER BY tech 
    CACHE (0.0ms) SELECT "projects".* FROM "projects" ORDER BY tech 
    CACHE (0.0ms) SELECT "projects".* FROM "projects" ORDER BY tech 
    CACHE (0.0ms) SELECT "projects".* FROM "projects" ORDER BY tech 
    CACHE (0.0ms) SELECT "projects".* FROM "projects" ORDER BY tech 
    Project Load (0.6ms) SELECT "projects".* FROM "projects" ORDER BY business_div 
    Project Load (0.5ms) SELECT "projects".* FROM "projects" ORDER BY project_owner 
    Project Load (0.7ms) SELECT "projects".* FROM "projects" ORDER BY status 
    (0.9ms) SELECT COUNT(*) FROM "projects" INNER JOIN "projecttechnols" ON "projecttechnols"."project_id" = "projects"."id" INNER JOIN "technols" ON "technols"."id" = "projecttechnols"."technol_id" WHERE "technols"."id" IS NULL 

这里是我的project.rb:

class Project < ActiveRecord::Base 
     attr_accessible :edited_first_name, :edited_last_name, :first_name, :last_name, :business_div, :client, :customer_benifits, :edited_date, :end_date, :entry_date, :financials, :industry, :keywords, :lessons_learned, :project_name, :project_owner, :role, :start_date, :status, :summary, :tech_id 

    validates_presence_of :business_div, :client, :customer_benifits, :end_date, :financials, :industry, :keywords, :lessons_learned, :project_name, :project_owner, :role, :start_date, :status, :summary#, :tech 



    has_many :projecttechnols 
    has_many :technols, :through => :projecttechnols 


    def self.like(text); "%#{text}%"; end 

     def self.search(search_client, search_industry, search_role, search_tech_id, search_business_div, search_project_owner, search_status, search_start_date_dd, search_start_date_A, search_start_date_B, search_keywords) 
     # start with a scoped query, to apply more scopes on it afterwards 
     _projects = Project.scoped 
     # then, for each of the parameters, apply the scope only if present 
     if search_client.present? 
      _projects = _projects.where ['client LIKE ?', like(search_client)] 
     end 
     if search_industry.present? 
      _projects = _projects.where ['industry LIKE ?', like(search_industry)] 
     end 
     if search_role.present? 
      _projects = _projects.where ['role LIKE ?', like(search_role)] 
     end 


     _projects = _projects.joins(:technols). 
       where("technols.id" => search_techs_ids) 

     if search_business_div.present? 
      _projects = _projects.where ['business_div LIKE ?', like(search_business_div)] 
     end 
     if search_project_owner.present? 
      _projects = _projects.where ['project_owner LIKE ?', like(search_project_owner)] 
     end 

     if search_status.present? 
      _projects = _projects.where ['status LIKE ?', like(search_status)] 
     end 



    todays_date = DateTime.now.to_date 

    if !search_start_date_A.blank? or !search_start_date_B.blank? 
     search_start_date_A = Date.parse(search_start_date_A).strftime("%Y-%m-%d") 
     search_start_date_B = Date.parse(search_start_date_B).strftime("%Y-%m-%d") 
     todays_date = nil 
     search_start_date_dd = nil 

     end 

    if search_start_date_dd.blank? 
     todays_date = nil 
    end 


    if search_start_date_A.present? or search_start_date_B.present? 

      _projects = _projects.where [' DATE(start_date) BETWEEN ? AND ?', search_start_date_A, search_start_date_B] 
     end 


        if search_start_date_dd.present? 
      _projects = _projects.where ['DATE(start_date) BETWEEN ? AND ?', search_start_date_dd, todays_date] 
     end 




     if search_keywords.present? 
      _projects = _projects.where ['keywords LIKE ?', like(search_keywords)] 
     end 
     # now you have applied only the present scopes. return the result, and watch 
     # the query as it executes. 
     _projects 
     end 


    def self.paginated_for_index(projects_per_page, current_page) 
     paginate(:per_page => projects_per_page, :page => current_page) 
     end 

    end 

Technol.rb:

class Technol < ActiveRecord::Base 
    attr_accessible :tech 

has_many :projecttechnols 
has_many :projects, :through => :projecttechnols 
end 

Projecttechnol.rb

class Projecttechnol < ActiveRecord::Base 
    attr_accessible :project_id, :technol_id 

belongs_to :technol 
belongs_to :project 
end 

任何人都可以正确地看到这项工作的解决方案。我是新手,因此请在尝试帮助我时记住这一点。在技​​术领域搜索任何内容都不会返回任何内容非常感谢

+0

您不需要Projecttechnol模型,只需在Project中声明'has_and_belongs_to_many:technols,:join_table =>“projecttechnols”'' – rewritten

回答

2

它看起来就像你在你的搜索参数有一个错字这里:

def self.search(search_client, search_industry, search_role, search_tech_id... 

但尚未使用search_techs_id这里:

_projects = _projects.joins(:technols).where("technols.id" => search_techs_ids) 

如果您检查您的查询,你可以看到,它试图加入一个空的两个表。

在另一方面,你的搜索查询是有点长,很难看,可我建议使用这样的事情:

class Project < ActiveRecord::Base 
    attr_accessible :edited_first_name, :edited_last_name, :first_name, :last_name, 
    :business_div, :client, :customer_benifits, :edited_date, :end_date, :entry_date, 
    :financials, :industry, :keywords, :lessons_learned, :project_name, :project_owner, 
    :role, :start_date, :status, :summary, :tech_id 

    validates_presence_of :business_div, :client, :customer_benifits, :end_date, 
    :financials, :industry, :keywords, :lessons_learned, :project_name, :project_owner, 
    :role, :start_date, :status, :summary#, :tech 

    has_many :projecttechnols 
    has_many :technols, :through => :projecttechnols 

    scope :client, { |client| where ['client LIKE ?', like(client) ] } 
    scope :industry, { |industry| where ['industry LIKE ?', like(industry)] } 
    scope :role, { |role| where ['role LIKE ?', like(search_role)] } 
    scope :technologies, { |technology_ids| joins(:technols).where("technols.id}" => technology_ids) } 
    scope :division, { |division| where ['business_div LIKE ?', like(search_business_div)] } 
    scope :owner, { |owner| where ['project_owner LIKE ?', like(search_project_owner)] } 
    scope :status, { |status| where ['status LIKE ?', like(search_status)] } 
    scope :keywords, { |keywords| where ['keywords LIKE ?', like(keywords)] } 
    scope :started_before, { |date| where ['start_date <= ?',date] } 
    scope :started_after, { |date| where ['start_date >= ?',date] } 

    def self.search_fields  
    [:client,:industry,:role,:technologies,:division,:owner,:status,:started_before,:started_after,:keywords] 
    end 

    def self.search(params) 
    search_fields.inject(scoped) do |scopes,key| 
     params[key].present? ? scopes.send(key,params[key]) : scopes 
    end 
    end 

    def self.like(text); "%#{text}%"; end 

    def self.paginated_for_index(projects_per_page, current_page) 
    paginate(:per_page => projects_per_page, :page => current_page) 
    end 

end 

这样,你的搜索方法是比较短一点,因为你已经将所有这些参数分解到它们自己的作用域中,如果您需要重用它们,方法已经存在。

希望这会有所帮助。

0

我想,在控制器中,您从窗体中获得正确的值。

这是您的params

{"utf8"=>"✓", "client"=>"", "industry"=>"", "role"=>"", "technols"=>{"id"=>["", "1", ""]}, "business_div"=>"", "project_owner"=>"", "start_date_dd"=>"", "start_date_A"=>"", "start_date_B"=>"", "status"=>"", "keywords"=>"", "per_page"=>"10"} 

所以选择technols ID列表是params["technols"]["id"]["", "1", ""]。如果这是有意的,那么你必须删除它的空白

tech_ids = params["technols"]["id"].reject(&:blank?) # removes empty strings 

并将其传递给搜索功能。如果不是有什么打算,然后检查你用它来创建选择框的代码,因为它必须回到正确的ID

+0

[“”,“1”,“”]是当我搜索第一个选项在collection_select中。[“”,“1”,“2”],当我选择时,[“”],当我不选择技术 – Jazz

+0

我添加了你的代码,并且我得到这个错误'undefined方法拒绝“1” :String' – Jazz

+0

你可以添加视图和控制器代码到你的问题? (也可以帮助清理所有用于创建选择标签的杂乱查询) – rewritten