2016-02-28 2 views
0

Я хотел был бы иметь возможность поиска заказов по id или по статусу заказа. Мой текущий код работает, но не 100%.Rails 4 Как искать по идентификатору заказа или статусу заказа

Имеются отношения has_many между моделями заказа и статуса заказа. Модель статус заказа имеет четыре элемента: 1.Processing, 2.Completed, 3.Cancelled, 4.Refunded

Пример:

У меня есть простая форма для ввода идентификатора заказа и другую форму с выберите тег со всеми статусами заказов для поиска по статусу заказа.

Если я ищу для заказа ID 1, я получаю все заказы с номером 1 в Ид, и я также получить все заказы со статусом заказа 1.

Я хотел получить результат либо идентификатор заказа или статус заказа.

модель Заказать

class Order < ActiveRecord::Base 
    belongs_to :order_status 

    def self.search(search) 
    where("cast(id as text) LIKE ? OR order_status_id LIKE ? ", "%#{search}%", "%#{search}%") 
    end 
end 

Статус заказа модель

class OrderStatus < ActiveRecord::Base 
    has_many :orders 
end 

Приказы Контроллер

def index 
    @order_statuses = OrderStatus.all 
    if params[:search] 
     @orders = Order.search(params[:search]) 
    else 
     @orders = Order.all 
    end 
    end 

Заказать просмотр индекса

<div class="row"> 
    <div class="col-sm-6 form-group"> 
     <%= form_tag orders_path, :method => 'get', class:"" do %> 
     <p> 
      <%= text_field_tag :search, params[:search] %> 
      <%= submit_tag "Search", :name => nil, class:"btn btn-primary" %> 
     </p> 
     <% end %> 
    </div> 
     <div class="col-sm-6 form-group"> 
     <%= form_tag orders_path, :method => 'get', class:"" do %> 
     <p> 
      <%= select_tag :search, options_from_collection_for_select(OrderStatus.all, :id, :name, params[:search]) %> 
      <%= submit_tag "Search", :name => nil, class:"btn btn-primary" %> 
     </p> 
     <% end %> 
    </div> 
</div> 
<table class="table"> 
    <tr> 
     <th>Order Id</th> 
     <th>amount</th> 
     <th>status</th> 
     <th>Last Updated</th> 
     <th>manage</th> 
    </tr> 
    <% @orders.each do |order| %> 
     <tr>    
     <td><%= order.id %></td> 
     <td><%= order.total %></td> 
     <td><%= order.order_status.name %></td> 
     <td><%= order.updated_at %></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> 

Я исследовал следующие ссылки, но я не найти или понять решение.

Ссылки:

http://railscasts.com/episodes/37-simple-search-form?autoplay=true

http://railscasts.com/episodes/111-advanced-search-form-revised?autoplay=true

http://guides.rubyonrails.org/active_record_querying.html

Rails Search Form

Build static dropdown menu for simple search Rails 3

ответ

2

Вы можете выполнить поиск по любому order_id или order_status :name атрибута со следующим

class Order < ActiveRecord::Base 
    belongs_to :order_status 

    def self.search(query) 
    query.to_s.is_i? ? where(id: query) : joins(:order_status).where('order_statuses.name LIKE ?', "%#{query}%") 
    end 
end 

Для того, чтобы использовать метод is_i? вам нужно будет расширить класс String, путем создания файла инициализация требует нового файла String расширения

# config/initializers/core_extensions.rb 
Dir[File.join(Rails.root, "lib", "core_extensions", "*.rb")].each {|f| require f } 

, а затем создать новый файл String расширения и is_i? метод

# lib/core_extensions/string.rb 
class String 
    def is_i? 
    /\A[-+]?\d+\z/ === self 
    end 
end 

кредит this SO answer для is_i? метода

+0

Спасибо, я попробую. Можете ли вы помочь мне немного разобраться в этом методе. Метод поиска принимает параметр (запрос). Может ли это быть чем угодно или нужно быть запросом, поиском или чем-то конкретным? Я немного смущен. – Asan

+0

метод '' 'search''' принимает аргумент' '' query''', который представляет собой строку, которая может содержать либо '' 'order_id''', либо какой-либо текст, который находится в' '' order_status: name атрибут '' '. для этого метод проверяет, отформатирован ли запрос как число (-ы) '' ''123'''' и предполагает, если он затем пытается выполнить поиск с помощью' '' 'order_id''', и если это не и запрос больше похож на этот '' '' foo'''', тогда он ищет '' 'orders''', которые принадлежат' '' order_statuses''' со словом '' '' foo''''' в колонка '' ': name''' – MilesStanfield

+0

Спасибо за объяснение. Я весь день царапаю себе голову. – Asan

0

Там нет необходимости бросать идентификатор в текст, а затем использовать нравится, чтобы соответствовать этому. Этого должно быть достаточно, чтобы получить то, что вам нужно.

class Order < ActiveRecord::Base 
    belongs_to :order_status 

    def self.search(search) 
    where("id = ? OR order_status_id LIKE ? ", search, "%#{search}%") 
    end 
end 
+0

Листинг, потому что это давало мне ошибку в производстве с использованием базы данных PG. кастинг решил проблемы. Спасибо за вашу помощь. – Asan