我有一个应用程序,用户可以在其中创建新项目并搜索以前的项目。在“创建新项目”页面上,用户可以选择为每个字段输入新信息,或者如果数据已在数据库中,则从下拉菜单中选择。至于搜索页面上的搜索功能。用户可以通过多种方式搜索许多不同的字段。
更新
根据下面的建议,我已经建立了一个包含每个项目的许多技术的表格。
搜索操作
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表中的新技术。我也无法使搜索正常工作。在技术领域中搜索任何内容都不会返回任何内容。
答案 0 :(得分:1)
好的,你的第三个问题是关于同一个项目,它开始清楚你要去哪里。
您是否考虑过将技术存储在单独的表中,以及与Product表关系的其他连接表?
通过这种方式,您可以为项目选择任意数量的技术,您可以只使用一个字段进行搜索(它只会获得与所选技术相关的项目),并且您将不会拥有如此复杂的代码。
使用选择标记选择项目表单中的技术。如果您希望项目对象至少具有一个技术或类似约束,请验证它。在整个“技术”表上使用选择来执行搜索框。并使用
if search_tech_id.present?
_projects = _projects.joins(:technologies).where("technologies.id" => search_tech_id)
end
而不是连接LIKEs的所有东西
编辑:一种搜索与许多技术相关的项目的方法。
要允许搜索“许多技术人员”,您可以使用多选字段。您还可以添加“AND”-ing或“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)