0

我有一个应用程序,用户可以在其中创建一个新项目并搜索以前的项目。在“创建新项目”页面上,用户可以选择为每个字段输入新信息,或者如果数据已经在数据库中,则从下拉菜单中进行选择。至于搜索页面上的搜索功能。用户可以在许多不同的领域、多种方式上进行搜索。

更新:

根据下面的建议,我已经建立了一个表格,其中包含每个项目的许多技术。

搜索动作

def search

@search = params[:client], params[:industry], params[:role], params[:tech_id], params[:business_div], params[:project_owner], params[:status], params[:start_date_dd], params[:start_date_A], params[:start_date_B],  params[:keywords]

@project_search = Project.search(*@search).order(sort_column + ' ' + sort_direction).paginated_for_index(per_page, page)

@search_performed = !@search.reject! { |c| c.blank? }.empty? 

   @project = Project.new(params[:project])


@all_technols = Technol.all

@technol = Technol.new(params[:tech])

params[:technols][:id].each do |technol|

if !technol.empty?

@project_technol = @project.projecttechnols.build(:technol_id => technol)

end
end

respond_to do |format|
      format.html # search.html.erb
      format.json { render :json => @project }
    end

end

新动作:

def new
    @project = Project.new

@all_technols = Technol.all

@project_technol = @project.projecttechnols.build


@project_technol = Projecttechnol.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @project }
    end

结尾

创建动作

def create
    @all_technols = Technol.all
    @project = Project.new(params[:project])

@technol = Technol.new(params[:tech])

params[:technols][:id].each do |technol|

if !technol.empty?



@project_technol = @project.projecttechnols.build(:technol_id => technol)

end
end
    @project.client = params[:new_client] unless params[:new_client].blank?
    @project.project_owner = params[:new_project_owner] unless params[:new_project_owner].blank?
    @project.tech = params[:new_tech] unless params[:new_tech].blank?
    @project.role = params[:new_role] unless params[:new_role].blank?
    @project.industry = params[:new_industry] unless params[:new_industry].blank?
    @project.business_div = params[:new_business_div] unless params[:new_business_div].blank?

    respond_to do |format|
      if @project.save
        format.html { redirect_to @project, notice: 'Project was successfully created.' }
        format.json { render json: @project, status: :created, location: @project }
      else
        format.html { render action: "new" }
        format.json { render json: @project.errors, status: :unprocessable_entity }
      end
    end
  end

新视图的技术部分:

<%= stylesheet_link_tag "new" %>


<h1>Create New Project</h1>





<div class="tech">
<%#= label_tag :new_tech, "Technologies Used :" %><br/>


<%= text_field_tag :new_tech, nil, :maxlength => 30 %>

Or
<%#= f.select( :tech, Project.all.map {|p| [p.tech]}.uniq, { :prompt => "Select a previous Technology"}, { :multiple => true, :size => 5 }) %>
<!/div>  

<% common_techs = [['Mainframe'],['UNIX'],['Windows Servers'],['Networking'],['CISCO'], ['Win7'], ['Telephony'], ['Web services'], ['Website'], ['Cloud'], ['Virtualisation'], ['Data Centre']] %>
 <% db_techs = Technol.all.map {|p| [p.tech]}.uniq %>

<% all_tech = common_techs + db_techs %>


<%= fields_for(@project_technol) do |ab| %>




<%= ab.label "Select previous technologies" %><br/>

<%= collection_select(:technols, :id, @all_technols, :id, :tech, {}, {:multiple => true} ) %>
</div>
<% end %>

    <%= stylesheet_link_tag "new" %>


<h1>Create New Project</h1>





<div class="tech">
<%#= label_tag :new_tech, "Technologies Used :" %><br/>


<%= text_field_tag :new_tech, nil, :maxlength => 30 %>

Or
<%#= f.select( :tech, Project.all.map {|p| [p.tech]}.uniq, { :prompt => "Select a previous Technology"}, { :multiple => true, :size => 5 }) %>
<!/div>  

<% common_techs = [['Mainframe'],['UNIX'],['Windows Servers'],['Networking'],['CISCO'], ['Win7'], ['Telephony'], ['Web services'], ['Website'], ['Cloud'], ['Virtualisation'], ['Data Centre']] %>
 <% db_techs = Technol.all.map {|p| [p.tech]}.uniq %>

<% all_tech = common_techs + db_techs %>


<%= fields_for(@project_technol) do |ab| %>




<%= ab.label "Select previous technologies" %><br/>

<%= collection_select(:technols, :id, @all_technols, :id, :tech, {}, {:multiple => true} ) %>
</div>
<% end %>





</div> <%#= small div %>





<% end %>



<div class="back_button2">
<%= button_to "Back", projects_path , :class => "button", :method => "get" %>
</div>



</div> <%#= small div %>





<% end %>



<div class="back_button2">
<%= button_to "Back", projects_path , :class => "button", :method => "get" %>
</div>

搜索页面:

<html>

<%= stylesheet_link_tag "search" %>
<body>
<div id ="title1">Exception Database Search</div>
<div id = "search_op">

<%= form_tag search_path, method: :get do %>


<div class="client">
Client : 
<%= select(@projects, :client, Project.order("client").map{|p| [p.client]}.uniq, :prompt => "-Any-", :selected => params[:client]) %></br>
</div>

<div class="industry">
Industry :
<%= select(@projects, :industry, Project.order("industry").map {|p| [p.industry]}.uniq, :prompt => "-Any-", :selected => params[:industry]) %></br>
</div>

<div class="role">
Role :
<%= select(@projects, :role, Project.order("role").map {|p| [p.role]}.uniq, :prompt => "-Any-", :selected => params[:role]) %></br>
</div>

<div class="tech">

<% common_techs = [['Mainframe'],['UNIX'],['Windows Servers'],['Networking'],['CISCO'], ['Win7'], ['Telephony'], ['Web services'], ['Website'], ['Cloud'], ['Virtualisation'], ['Data Centre']] %>
 <% db_techs = Project.order("tech").map {|p| [p.tech]}.uniq %>

<% all_tech = Project.order("tech").map {|p| [p.tech]} + Project.order("tech").map {|p| [p.tech2]} + Project.order("tech").map {|p| [p.tech3]} + Project.order("tech").map {|p| [p.tech4]} + Project.order("tech").map {|p| [p.tech5]} %>





<%= fields_for(@project_technol) do |ab| %>



<%= collection_select(:technols, :id, @all_technols, :id, :tech, {}, {:multiple => true } ) %>
</div>
<% end %>


<div class="business_div">
Business Division :

<%= select(@projects, :business_div, Project.order("business_div").map {|p| [p.business_div]}.uniq, :prompt => "-Any-", :selected => params[:business_div]) %></br>
</div>


<div class="project_owner">  
Project Owner :
<%= select(@projects, :project_owner, Project.order("project_owner").map {|p| [p.project_owner]}.uniq, :prompt => "-Any-", :selected => params[:project_owner]) %></br>
</div>


<div class="date1">
Select start dates from :
<%= select_tag "start_date_dd", options_for_select({
    "Select a period" => "",
      "3 days ago"   => DateTime.now.to_date - 3.days,   # =    259_200 sec.
      "1 week ago"   => DateTime.now.to_date - 1.week,   # =    604_800 sec.
      "1 month ago"  => DateTime.now.to_date - 1.month,  # =  2_592_000 sec.
      "6 months ago" => DateTime.now.to_date - 6.months, # = 15_552_000 sec.
      "1 year ago"   => DateTime.now.to_date - 1.year,   # = 31_557_600 sec.
    }, :selected=>params[:start_date_dd] )%>

</div>

<%#= until now <%= l DateTime.now.to_date %><%#=,%>   
<h4> OR</h4> 

<div class="date2">
exact start dates

<%=  text_field_tag :start_date_A, params[:start_date_A], :style => 'width: 80px;' %>


-

<%=  text_field_tag :start_date_B, params[:start_date_B], :style => 'width: 80px;' %></br>
</div>






<div class="status">
Status :

<%= select(@projects, :status, Project.order("status").map {|p| [p.status]}.uniq, :prompt => "-Any-", :selected => params[:status]) %></br>
</div>



<div class="keywords">
Keywords :

<%= text_field_tag :keywords, params[:keywords] %></br>
</div>




<div class="results">
Results per page: <%= select_tag :per_page, options_for_select([10,20,50], :selected=>params[:per_page]),  { :onchange => "this.form.submit();"}   %></br>


<div class="buttons">
<div id="search_button">
<%= submit_tag "Search", name: nil, :class => "button" %>
</div>

<% end %>

<div class="home_button">
<%= button_to "Home", projects_path, :class => "button", :method => "get"  %>
</div>



<div id="reset_button">
<%= button_to "Reset Search", search_path, :class => "button", :method => "get" %>
</div>


</div>
</div> <%#search_op div%>







<div class ="menu"></div>



<div id ="section3">

<% if @project_search.total_entries > 0 %>
<% if @search_performed %>





<% if @search_performed %>
<%= hidden_field_tag :direction, params[:direction] %>
<%= hidden_field_tag :sort, params[:sort] %>
<%= hidden_field_tag :per_page, params[:per_page] %>
<%= hidden_field_tag :page, params[:page] %>


<%= will_paginate (@project_search), :class => 'will' %>

<% end %>



</body>


</html> 

楷模:

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

belongs_to :technol
belongs_to :project
end

class Technol < ActiveRecord::Base
  attr_accessible :tech

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

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


validates_format_of :industry, :with => /\A[a-zA-Z]+\z/, :message => "field should only have letters"
validates_format_of :business_div, :with => /\A[a-zA-Z]+\z/, :message => "field should only have letters"
validates_format_of :client, :with => /\A[a-zA-Z]+\z/, :message => "field should only have letters"
validates_format_of :project_owner, :with => /\A[a-zA-Z]+\z/, :message => "field should only have letters"
validates_format_of :role, :with => /\A[a-zA-Z]+\z/, :message => "field should only have letters"

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_exception_pm, 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


    if search_tech_id.present?
  _projects = _projects.joins(:technols).where("tech.id" => search_tech_id)
end

    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

我似乎无法将“新项目页面”上的新技术保存在 Technols 表中。我也无法让搜索正常工作。在技​​术领域搜索任何东西都不会返回任何结果。

4

1 回答 1

1

好的,关于同一个项目的第三个问题,你开始清楚你想去哪里。

您是否考虑将技术存储在一个单独的表中,并为与 Product 表的关系存储一个附加的连接表?

这样,您可以为一个项目选择任意数量的技术,您可以只使用一个字段进行搜索(它只会获得与所选技术相关的项目)并且您不会有如此复杂的代码。

使用选择标签来选择项目表单中的技术。如果您希望项目对象具有至少一种技术或类似约束,请验证该项目对象。使用整个“技术”表上的选择来执行搜索框。并使用

if search_tech_id.present?
  _projects = _projects.joins(:technologies).where("technologies.id" => search_tech_id)
end

而不是所有连接 LIKE 的东西

编辑:一种搜索与许多技术相关的项目的方法。

要允许搜索“许多技术”,您可以使用多选字段。您还可以为条件添加“AND”或“OR”选项(即,搜索与所有选定技术或任何选定技术相关的 porjocets。

在控制器中,当您获得技术 ID 列表时,要搜索具有所有选定技术的项目,您必须使用一些 SQL 魔术:

n_techs = search_techs_ids.size
_projects = _projects.joins(:technologies).
              select("projects.*").
              where("technologies.id" => search_tech_ids).
              group("projects.*").
              having("count(technologies.id) = #{n_techs}")

另一方面,要在选定的技术中搜索任何技术,您可以这样做

_projects = _projects.joins(:technologies).
              where("technologies.id" => search_tech_ids)
于 2012-10-02T10:41:23.270 回答