我知道我的代码很笨重,但我想在我的GUEST
数据库中为不同的列创建一个包含多个文本框的表单。表单不起作用,我的所有访客条目仍然列出(列表不会被搜索范围缩小)。如果有人能指出我正确的方向,那将是非常棒的。另外guest.rb代码怎么能更简洁?
控制器:
def index
@guests = Guest.all
if params[:search_first_name]
@guests = Guest.search_first_name(params[:search_first_name])
end
if params[:search_last_name]
@guests = Guest.search_last_name(params[:search_last_name])
end
if params[:search_email]
@guests = Guest.search_email(params[:search_email])
end
if params[:search_phone]
@guests = Guest.search_phone(params[:search_phone])
end
end
guest.rb
def self.search_first_name(query)
# where(:email, query) -> This would return an exact match of the query
where("first_name like ?", "%#{query}%")
end
def self.search_last_name(query)
# where(:email, query) -> This would return an exact match of the query
where("last_name like ?", "%#{query}%")
end
def self.search_email(query)
# where(:email, query) -> This would return an exact match of the query
where("email like ?", "%#{query}%")
end
def self.search_phone(query)
# where(:email, query) -> This would return an exact match of the query
where("phone like ?", "%#{query}%")
end
的index.html:
<%= form_tag(guests_path, :method => "get", class: "navbar-form", id: "search-form") do %>
<div class="input-append col-sm-10">
<div class="row">
<div class="col-sm-4">
<p><%= text_field_tag :search_first_name, params[:search_first_name], placeholder: "First Name", style: "width:100%;" %></p>
<p><%= text_field_tag :search_last_name, params[:search_last_name], placeholder: "Last Name", style: "width:100%;" %></p>
</div>
<div class="col-sm-4">
<p><%= text_field_tag :search_email, params[:search_email], placeholder: "Email Address", style: "width:100%;" %></p>
<p><%= text_field_tag :search_phone, params[:search_phone], placeholder: "Phone Number", style: "width:100%;" %></p>
</div>
<div class="col-sm-4">
</div>
<%= submit_tag 'Search Guests' %>
</div>
</div>
<% end %>
<table class="table table-hover col-sm-12">
<thead>
<tr>
<th>Guest ID</th>
<th>Guest Name</th>
<th>Email</th>
<th>Phone</th>
<th></th>
</tr>
</thead>
<tbody>
<% @guests.each do |guest| %>
<tr>
<td>G-00<%= guest.id %></td>
<td><%= guest.first_name %> <%= guest.last_name %></td>
<td><%= guest.email %></td>
<td><%= guest.phone %></td>
<td style="text-align:right;"><%= link_to 'View Guest Profile', guest, :class => "btn btn-sm btn-success" %> <%= link_to 'Edit', edit_guest_path(guest), :class => "btn btn-sm btn-default" %> <%= link_to 'Destroy', guest, method: :delete, data: { confirm: 'Are you sure?' }, :class => "btn btn-sm btn-danger" %></td>
</tr>
<% end %>
</tbody>
</table>
答案 0 :(得分:3)
问题来了,因为没有值的param将等于""
,但在Ruby中仍然是true
,所以基本上如果你的search_phone
是空的那么你会看到所有结果,因为if params[:search_phone]
将为true,因此将运行块,并且运行的最终代码将等同于:
@guests = Guest.where( "phone like '%%'" )
这只是两个通配符,因此会返回所有结果。其他人已经提到将条件更改为使用.present?
,因此如果它是空白则不会运行。
您还询问了重构代码的问题,我会这样写:
def index
@guests = Guest.search_or_all params
end
def self.search_or_all params={}
query = %i[first_name last_name email phone].map do |k|
kk = "search_#{k}"
sanitize_sql ["#{k} LIKE '%s'", "%#{params[kk]}%"] if params[kk]
end.compact.join " OR "
where query
end
答案 1 :(得分:2)
没有深入到代码重构。尝试将params[:field_name].present?
添加到所有if
语句中。
答案 2 :(得分:-1)
你应该把"^#{query}"
作为正则表达式
这样,您的Guest.rb文件将如下所示
Guest.rb
def self.search_first_name(query)
# where(:email, query) -> This would return an exact match of the query
where("first_name like ?", "^#{query}")
end
def self.search_last_name(query)
# where(:email, query) -> This would return an exact match of the query
where("last_name like ?", "^#{query}")
end
def self.search_email(query)
# where(:email, query) -> This would return an exact match of the query
where("email like ?", "")
end
def self.search_phone(query)
# where(:email, query) -> This would return an exact match of the query
where("phone like ?", "%#{query}%")
end