将复杂的mysql select转换为Rails 3.1

时间:2012-03-14 19:59:06

标签: mysql ruby-on-rails

我有三个表'硬件','仓库'和'品牌'和表格以这种方式一起引用:硬件< - >仓库硬件< - >品牌

在仓库视图中,我有一个以这种方式工作的搜索下拉菜单:从菜单中选择“品牌”,当您单击“提交”时,应用程序将返回与您相关的所有仓库对象选用。 问题是仓库表与我之前显示的品牌无关,所以不是加入仓库和品牌的任何外键。 所以我必须尝试在rails应用程序中转换这个mysql查询的方法:

SELECT w1。* FROM warehouses w1,hardwares h1 where w1.hardware_id = h1.id and h1.brand_id = 3

这是我的代码:

class WarehousesController < ApplicationController
def search
        generate_selects true
        respond_to do |format|
            format.html # search.html.erb
            format.js {render :partial => 'get_models'}
            format.xml  { render :xml => @warehouse }
        end
    end

    def search_result
        if request.post? && params[:from_form]
            session[:sa_query_flatten] = sa_query.flatten #Memorizzo sulla session per riutilizzarla in "aggregate_by_position" e will_paginate per page > 1
        end
        conditions  = session[:sa_query_flatten]
        logger.debug "QUERY: #{conditions} SESSION:#{session[:sa_query_flatten].inspect}"
        @products = Warehouse.find(:all,:conditions => conditions)
        @search_count = @products.count
        @products = @products.paginate(:page => params[:page], :per_page => 100)
        @search_start = ((params[:page].to_i - 1)* 100) + 1
        @search_end = (params[:page].to_i * 100) - 1
        if @search_start < 0
        @search_start = @search_start + 100
        end
        if @search_end < 0
        @search_end = @search_end + 100
        end
        if @search_end > @search_count
        @search_end = @search_count
        end
        respond_to do |format|
            format.html
            format.js
        end
    end

def generate_selects(search)
        if !search
            @hardwares ||= Hardware.where({:brand_id => @warehouse.hardware.brand_id}).map{|hw| [hw.model,hw.id]}.sort
            if session[:user_role] != "administrator"
                @ingress_transport_documents = IngressTransportDocument.filtered_by_registry(session[:registry_id]).map{|itd| [itd.number,itd.id]}.sort
            else
                @ingress_transport_documents = IngressTransportDocument.all.map{|itd| [itd.number,itd.id]}.sort
            end
        end 
            @brands = Brand.all.map{|br| [br.name,br.id]}.sort
            @positions = Position.all.map{|pos| [pos.name,pos.id]}.sort
            @states = State.all.map{|st| [st.name,st.id]}.sort
            @logicalWH = Logicalwarehouse.all.map{|lw| [lw.name,lw.id]}.sort
            @extra = Extra.all.map{|ex| [ex.name,ex.id]}.sort
            @registries = Registry.all.map{|cs| [cs.name,cs.id]}.sort

    end


    def sa_query
        if params[:warehouse]
            session[:params_warehouse] = params[:warehouse]
        else
            params[:warehouse] = session[:params_warehouse]
        end
        query = String.new
        query_array = Array.new
        if params[:enable_asset] == "1"
            query << "asset LIKE ? AND "
            query_array.push(params[:asset] + "%")
        end
        if params[:enable_serial] == "1"
            query << "serial LIKE ? AND "
            query_array.push params[:serial] + "%"
        end
        if params[:enable_brand] == "1"
            query << "**brand** =>  = ? AND "
            query_array.push Brand.find(params[:brand]).name # Qui va messo brand, non brand_value
        end
        if params[:enable_model] == "1"
            query << "hardware_id.model = ? AND "
            query_array.push params[:model]
        end
        if params[:enable_position] == "1" 
            query << "position_id = ? AND "
            query_array.push params[:position]

        end
        if params[:enable_logicalwarehouse] == "1"
            query << "logicalwarehouse_id = ? AND "
            query_array.push params[:logicalwarehouse]
        end
        if query.index("AND ",-4) != nil
        query = query[0,query.length-5]
        end
        [query,query_array]
    end

Mysql等待品牌作为查询输入参数,有什么建议吗?

1 个答案:

答案 0 :(得分:0)

如果您使用rails,我的建议是退后一步,尝试在rails本身中执行更多查询,并尽可能使用最佳模型设置。

我会按如下方式构建你的3个模型:

class Warehouse < ActiveRecord::Base
  has_many : brands
  has_many : hardwares, :through => brands
end


class Brand < ActiveRecord::Base
  belongs_to :hardware
  belongs_to :warehouse
end

class Hardware < ActiveRecord::Base
  has_many :brands
  has_many :warehouses, :through => brands
end

然后,此结构将允许您执行所需的Brand.hardwaresBrand.warehouses个查询。只需为您想要的品牌添加find