2016-03-21 11 views
4

Ich habe Aufträge nach Datumsbereich abgefragt. Es funktioniert jetzt aber ich habe die Logik in der Steuerung nicht im Modell. Ich weiß, dass dies stattdessen im Modell sein sollte. Ich habe mehrere Ansätze ausprobiert, aber ich hatte kein Glück.Rails 4 Active Record-Abfrage

Frage: Was ist der richtige Weg, dies zu tun?

Ich bin auf der Suche an den Rails Guides Active Record Querying Abschnitt 2.2 Array Bedingungen: http://guides.rubyonrails.org/active_record_querying.html

Auch mehrere Frage hier in Stack-Überlauf erforscht: 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 Leer jetzt Fehler

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 zu vermeiden Hier bin ich Eingabe der Datumsbereich

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

Antwort

1

ich nahm Freiheit, auch den Verein, order_status, eifrig zu laden, denn aus Ihrer Sicht sieht es so aus, als ob Sie r sind auf diese Tabelle zugreifen. Hier ist ein solid guide auf eifrig laden.

Im Folgenden erhalten Sie Ihre Lösung. Gut für Sie, wenn Sie die richtige Abfrage in Ihren Controller schreiben und die Notwendigkeit erkennen, Ihr Modell umzuformatieren. Das Folgende wird ebenfalls nicht getestet, also lassen Sie es mich wissen, wenn es nicht die Ergebnisse liefert, die Sie brauchen. Der unten stehende Code kann auch zu Fehlern führen, wenn die Parameter keine gültigen Datumsangaben sind. Daher sollten Sie möglicherweise weiter gehen, um sicherzustellen, dass Fehler korrekt verarbeitet werden.

# 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) } 

Sie könnten sogar einen Schritt weiter gehen und dies mit dem Abfrageobjektmuster umgestalten.

# 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 
+0

Danke Justin für den Lebensretter. Ich werde definitiv mehr über Scopes lernen. Danke auch für den zusätzlichen Code. – Asan