如何从Rails关联中获取属性

时间:2015-10-27 09:37:33

标签: ruby-on-rails

我有一个搜索表单,用于搜索特定模型(订单)。它工作正常但我想在我的搜索方法中添加一个参数来自一个关联(事务),这个参数嵌套如下:[" params"] [" transaction_id"]。下面,我收到错误ActiveRecord::StatementInvalid in Orders#index,因为我无法以正确的方式表达。我该如何解决这个问题?

型号:

class Order < ActiveRecord::Base
  has_many :transactions, :class_name => "OrderTransaction"

  def self.search(params)
    query = order('created_at DESC').joins(:transactions)
    query = query.where('name LIKE ? OR email LIKE ? OR phone LIKE ? OR address1 LIKE ? OR state LIKE ? OR city LIKE ? OR **params.transaction_id** LIKE ?', "%#{params[:search]}%", "%#{params[:search]}%", "%#{params[:search]}%", "%#{params[:search]}%", "%#{params[:search]}%", "%#{params[:search]}%", "%#{params[:search]}%").order('created_at DESC') if params[:search].present?
    query
  end
end

控制器:

def index
  @orders = Order.search(params)
end

查看:

<%= form_tag orders_path, :method => 'get' do %>
  <p>
    <%= text_field_tag :search, params[:search],id: "search_text", placeholder: "   Search order" %>
    <%= submit_tag "Search", :name => nil, class: "btn btn-success", id: "search_but_order" %>
  </p>
<% end %>

解决方案 正如@Lanny Bose建议的那样,我为我的Order模型创建了一个新列,并将序列化参数的值传递给它。通过这种方式,我现在可以将它添加到我的搜索方法中。

3 个答案:

答案 0 :(得分:1)

在开始之前,Order.search中有一个逻辑错误。您正在设置query =两次,这意味着您只是在另一个上面编写一个查询。你想把它们连在一起。

至于如何构建查询,你就是在正确的轨道上。

<强>模型

def self.search(term)
  if term
    Order.order('created_at DESC').joins(:transactions).where("name LIKE :t OR email LIKE :t", t: term)
  else
    nil
  end
end

请注意:t周围的新语法。 Rails称之为占位符条件in the Rails Guide,这意味着您不必一遍又一遍地复制搜索变量。

另外,我意识到我只与nameemail进行了比较。我会让你输入其余的字段。 :)

修改

对不起,我忽略了拼出这个。我会在控制器中进行参数处理,所以我只是将一个字符串传递给模型。

<强>控制器

@orders = Order.search(params[:search])

......这绝对是一种风格超过实质的问题,我相信。

答案 1 :(得分:0)

嘿,你可以试试这种方式。如果你的列是序列化然后你可以在传递搜索字符串之前使用.to_yaml转换器,在这种情况下你需要创建相同的哈希值,因为你在商店时串行化

我们可以使用yaml创建你的字符串:

 yml_str = {:transcation_id => params[:search] }.to_yaml.gsub("-","").squish

您可以使用.squishgsub方法从字符串中删除不需要的---\n

只是您从特定列的查询

Order.includes(:transactions).where("order_transactions.params like ?", "%#{yml_str}%")

你的方法

def self.search(params)

    query = order('created_at DESC').joins(:transactions)
    query = query.where('name LIKE ? OR email LIKE ? OR phone LIKE ? OR address1 LIKE ? OR state LIKE ? OR city LIKE ? OR order_transactions.params LIKE ?', "%#{params[:search]}%", "%#{params[:search]}%", "%#{params[:search]}%", "%#{params[:search]}%", "%#{params[:search]}%", "%#{params[:search]}%", "%#{yml_str}%").order('created_at DESC') if params[:search].present?
    query
  end

答案 2 :(得分:0)

您是否考虑使用范围?

class Order < ActiveRecord::Base
  scope :name, -> (name) { where("name like ?", "#{name}%")}
  scope :email, -> (email) { where("email LIKE ?", "#{email}%")}
  scope :phone, -> (phone) { where("phone LIKE ?", "#{phone}%")}
  scope :address1, -> (address1) { where("address1 LIKE ?", "#{address1}%")}
  scope :state, -> (state) { where("state LIKE ?", "#{name}%")}
  scope :city, -> (city) { where("city LIKE ?", "#{city}%")}

  scope :custom, -> (field, value) { where("#{field} LIKE ?", "#{value}%")}

end

现在我们可以通过以下方式解决嵌套的params问题:

q=params[:search]
if q.present?
   result = Order.name(q).or.email(q).or.phone(q).or.address1(q).or.state(q).or.city(q)
    if params[:nested_query]
       hash.each do |key, value|
          result=result.or(key,value)
       end
    end
end