2

我试图概括多个模型/视图/控制器将使用的几种方法,但我没有运气。这是仅适用于一组称为卡车的原始代码。

看法

<h2>Trucks</h2>
  <%= form_tag trucks_path, :method => 'get' do %>
  <%= hidden_field_tag :direction, params[:direction] %>
  <%= hidden_field_tag :sort, params[:sort] %>
  <p>
    Search: 
    <%= text_field_tag :search %>
    by 
    <%= select_tag :search_column, options_for_select(Truck.translated_searchable_columns(['attribute1']), params[:search_column]) %>
    <%= submit_tag "Search" %>
  </p>
<% end %>

<!-- Display code goes here, but im not showing since its just a table -->

控制器

    def index
    @trucks = Truck.search(params[:search], params[:search_column]).order(sort_column(Truck, "truck_no") + " " + sort_direction)

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @trucks }
    end
  end

模型

  class Truck < ActiveRecord::Base
  attr_accessible :attribute1, :attribute2, :attribute3

  def self.search(keyword, column_name)
    if self.column_names.include?(column_name.to_s)
      where("trucks.#{column_name} LIKE ?", "%#{keyword}%")
    else
      scoped
    end
  end

  def self.searchable_columns(unwanted_columns)
    self.column_names.reject{ |column| unwanted_columns.include?(column) }
  end

  def self.translated_searchable_columns(unwanted_columns)
    columns = self.searchable_columns(unwanted_columns)
    result = columns.map{ |column| [Truck.human_attribute_name(column.to_sym), column] }
    result
  end
end

所有这一切都顺利进行,现在我无法弄清楚如何将这些方法移动到 lib 并将它们泛化,以便让 Trailers 能够调用相同的方法并传递其信息并实现同样的结果。我正在尝试使此代码尽可能干燥。谁能解释我需要做些什么来实现这一目标?lib如何访问数据库?

4

1 回答 1

3

您正在寻找的概念称为“关注”。Rails 有一个方便的模块来实现称为ActiveSupport::Concern的关注点。以下是提取模型方法的方法:

module Searchable
  extend ActiveSupport::Concern

  module ClassMethods
    def search(keyword, column_name)
      if column_names.include?(column_name.to_s)
        where("#{table_name}.#{column_name} LIKE ?", "%#{keyword}%")
      else
        scoped
      end
    end

    def searchable_columns(unwanted_columns)
      column_names.reject{ |column| unwanted_columns.include?(column) }
    end

    def translated_searchable_columns(unwanted_columns)
      columns = searchable_columns(unwanted_columns)
      columns.map{ |column| [human_attribute_name(column.to_sym), column] }
    end
  end
end

然后在你的模型中:

class Truck < ActiveRecord::Base
  include Searchable
  attr_accessible :attribute1, :attribute2, :attribute3
end

至于你应该在哪里存储Searchable模块,这取决于你——它必须是包含在的某个地方,config.autoload_paths就像模型或控制器一样。Rails 4 引入了一个约定,模型关注点存储在 中app/models/concerns,控制器关注点存储在 中app/controllers/concerns,但除了默认自动加载之外,这些位置没有什么特别之处。

于 2013-08-13T14:57:29.480 回答