我按日期范围查询订单。 现在正在使用,但我在控制器中的逻辑不在模型中。我知道这应该在模型中。 我尝试了几种方法,但我没有运气。
问题: 这样做的正确方法是什么?
我正在查看Rails指南活动记录查询部分2.2数组条件: http://guides.rubyonrails.org/active_record_querying.html
还在堆栈溢出中研究了几个问题: undefined local variable or method `params' for #<Result:0x3904b18>
undefined local variable or method `user_params' rails 4
ruby query between two date parameters
orders.rb 立即清空以避免错误
def self.search_range
end
orders_controller.rb
def search_range
@orders = Order.where("created_at >= :start_date AND created_at <= :end_date",{start_date: params[:start_date], end_date: params[:end_date]}).order("created_at desc")
end
search_range.html.erb 我在这里输入日期范围
<div class="container-fluid events-container">
<div class="row">
<div class="col-sm-12">
<h1>Orders</h1>
</div>
</div>
<div class="row">
<div class="col-sm-6 form-group">
<%= form_tag search_range_path, :method => 'get', class:"" do %>
<p>
<%= text_field_tag :start_date, params[:start_date] %>
<%= text_field_tag :end_date, params[:end_date] %>
<%= submit_tag "Search", :name => nil, class:"btn btn-primary" %>
</p>
<% end %>
</div>
</div>
<table class="table">
<tr>
<th>amount</th>
<th>status</th>
<th>Last Updated</th>
<th>Order Id</th>
<th>manage</th>
</tr>
<% @orders.each do |order| %>
<tr>
<td><%= order.total %></td>
<td><%= order.order_status.name %></td>
<td><%= order.created_at.strftime("%m/%d/%Y") %></td>
<td><%= order.id %></td>
<td><%= link_to 'details', order %> |
<%= link_to 'edit', edit_order_path(order) %> |
<%= link_to 'delete', order_path(order), method: :delete, data: { confirm: 'Are you sure?' } %>
</td>
</tr>
<% end %>
<tr><td colspan="4"></td></tr>
</table>
<div class="row">
<div class="col-sm-12">
<hr>
</div>
</div>
</div>
答案 0 :(得分:1)
我冒昧地也热切地加载关联order_status
,因为在你的视图中看起来你正在引用该表。这是热切加载的solid guide。
下面应该会帮助您解决问题。适合在控制器中编写正确的查询,并认识到需要重构模型。以下也没有经过测试,所以如果它不能产生您需要的结果,请告诉我。如果params不是有效日期,下面的代码也可能导致错误,因此您可能希望进一步确保它正确处理错误。
# controller
@orders = Order.includes(:order_status).
filter_between_dates(params[:start_date], params[:end_date]).
recent
# model
scope :filter_between_dates, (lambda do |start_date, end_date|
return all unless start_date.present? && end_date.present?
where('created_at >= ? AND created_at <= ?', start_date, end_date)
end)
# Order based on created_at date.
#
# examples:
# Order.recent
# Order.recent('asc')
scope :recent, -> (default = 'desc') { order(created_at: default.to_sym) }
你甚至可以更进一步,使用查询对象模式重构它。
# app/finders/orders/search_finder.rb
module Orders
class SearchFinder
attr_reader :params
def initialize(params)
@params = params
end
def execute
Order.includes(:order_status).
filter_between_dates(params[:start_date], params[:end_date]).
recent
end
end
end
# controller
@orders = Orders::SearchFinder.new(params).execute