Rails 4 Active Record Querying

时间:2016-03-21 00:49:24

标签: ruby-on-rails ruby-on-rails-4 activerecord

我按日期范围查询订单。 现在正在使用,但我在控制器中的逻辑不在模型中。我知道这应该在模型中。 我尝试了几种方法,但我没有运气。

问题: 这样做的正确方法是什么?

我正在查看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>

1 个答案:

答案 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