Ruby on rails 如何在rails模型中调用可重用代码?

Ruby on rails 如何在rails模型中调用可重用代码?,ruby-on-rails,helper,Ruby On Rails,Helper,我在我的模型中有一个重复的方法,我想把这些代码放在一个地方,只想在我的模型中访问它 我的模型有以下几种方法: class ProductionProductivity7 < ApplicationRecord def self.import1(file) spreadsheet = Roo::Spreadsheet.open(file.path) header = spreadsheet.row(1) (2..spreadsheet.last_row).

我在我的模型中有一个重复的方法,我想把这些代码放在一个地方,只想在我的模型中访问它

我的模型有以下几种方法:

class ProductionProductivity7 < ApplicationRecord
def self.import1(file)
  spreadsheet = Roo::Spreadsheet.open(file.path)
        header = spreadsheet.row(1)
        (2..spreadsheet.last_row).each do |i|
          row = Hash[[header, spreadsheet.row(i)].transpose]
          puts row.to_hash
          product = find_by(id: row["id"]) || new
          product.attributes = row.to_hash
          product.save!
    end
end
def self.search(search,compare)
  if search == "All"
    all.order(:id)
  elsif compare == "Bihar vs District"
    where("Districts = ? OR Districts = ?", search, "Bihar")
  else
    where(Districts: search)
  end
end
我在我的模型中包含了这一点,但我得到了以下错误:

undefined method `ProductionProductivity7sHelper' for ApplicationController:Class
 undefined method `search' for #<Class:0x00007ff115974fd8> Did you mean? search1
我的控制器代码如下:

 def test
      @ProductionProductivity7s = ProductionProductivity7.search(params[:search],compare)
      a = ProductionProductivity7.query(@ProductionProductivity7s,params[:year],rain_fall_type,views,compare)
 end 
我在app文件夹中添加了一个模块名code.rb

   module Code
    def search(search_scope,compare)
        if search_scope == "All"
        all.order(:id)
        elsif compare == "Bihar vs District"
        where("Districts = ? OR Districts = ?", search_scope, "Bihar")
        else
        where(Districts: search_scope)
        end
    end
end
我只想把我的模型的所有方法写在某个地方,它可以是模块,也可以是助手,而不做任何更改。是否可能我只想在我的模型中使用这个代码块

我在gist文件中添加了整个控制器代码和模型代码。请看一看

我得到这个错误:

undefined method `ProductionProductivity7sHelper' for ApplicationController:Class
 undefined method `search' for #<Class:0x00007ff115974fd8> Did you mean? search1
未定义的搜索方法#你的意思是?搜索1

制作一个模块,比如:

module Import1

  def import1(file)
    spreadsheet = Roo::Spreadsheet.open(file.path)
    header = spreadsheet.row(1)
    (2..spreadsheet.last_row).each do |i|
      row = Hash[[header, spreadsheet.row(i)].transpose]
      puts row.to_hash
      product = find_by(id: row["id"]) || new
      product.attributes = row.to_hash
      product.save!
    end
  end

  def search(search_scope,compare)
    if search_scope == "All"
      all.order(:id)
    elsif compare == "Bihar vs District"
      where("Districts = ? OR Districts = ?", search_scope, "Bihar")
    else
      where(Districts: search_scope)
    end
  end

end
我想我会把它放在你的
应用程序
文件夹的某个地方,这样你就不会有自动加载的问题了。你可以把它放在你的root
app
文件夹中,但这对我来说似乎很混乱。你也可以把它放在你的
models
文件夹里,但是在同一个文件夹里有两种截然不同的东西,这对我来说也很混乱。我想我会尝试创建一个新文件夹,比如
app/model\u modules
或者
app/shared\u model\u modules
并将您的
import\u 1.rb
文件放在其中。那么,文件是什么就很清楚了

然后做:

class ProductionProductivity7 < ApplicationRecord
  extend Import1
end
然后,您的文件导入服务可能如下所示:

class ImportFileService < BaseService

  def call
    spreadsheet = Roo::Spreadsheet.open(file.path)
    header = spreadsheet.row(1)
    (2..spreadsheet.last_row).each do |i|
      row = Hash[[header, spreadsheet.row(i)].transpose]
      puts row.to_hash
      product = klass.find_or_initialize_by(id: row["id"])
      product.attributes = row.to_hash
      product.save!
    end
  end

end
ImportFileService.call(file: file, klass: ProductionProductivity7)

制作一个模块,比如:

module Import1

  def import1(file)
    spreadsheet = Roo::Spreadsheet.open(file.path)
    header = spreadsheet.row(1)
    (2..spreadsheet.last_row).each do |i|
      row = Hash[[header, spreadsheet.row(i)].transpose]
      puts row.to_hash
      product = find_by(id: row["id"]) || new
      product.attributes = row.to_hash
      product.save!
    end
  end

  def search(search_scope,compare)
    if search_scope == "All"
      all.order(:id)
    elsif compare == "Bihar vs District"
      where("Districts = ? OR Districts = ?", search_scope, "Bihar")
    else
      where(Districts: search_scope)
    end
  end

end
我想我会把它放在你的
应用程序
文件夹的某个地方,这样你就不会有自动加载的问题了。你可以把它放在你的root
app
文件夹中,但这对我来说似乎很混乱。你也可以把它放在你的
models
文件夹里,但是在同一个文件夹里有两种截然不同的东西,这对我来说也很混乱。我想我会尝试创建一个新文件夹,比如
app/model\u modules
或者
app/shared\u model\u modules
并将您的
import\u 1.rb
文件放在其中。那么,文件是什么就很清楚了

然后做:

class ProductionProductivity7 < ApplicationRecord
  extend Import1
end
然后,您的文件导入服务可能如下所示:

class ImportFileService < BaseService

  def call
    spreadsheet = Roo::Spreadsheet.open(file.path)
    header = spreadsheet.row(1)
    (2..spreadsheet.last_row).each do |i|
      row = Hash[[header, spreadsheet.row(i)].transpose]
      puts row.to_hash
      product = klass.find_or_initialize_by(id: row["id"])
      product.attributes = row.to_hash
      product.save!
    end
  end

end
ImportFileService.call(file: file, klass: ProductionProductivity7)

当然,您可以这样创建一个模块:

module ProductionProductivity7sHelper
  def import1(file) # notice I dropped 'self.'

    ...

  end

  ...

end
然后在课堂上,添加:

class ProductionProductivity7 < ApplicationRecord
  extend ProductionProductivity7sHelper

  ...

end
class ProductionProductivity7

这将添加模块中定义为ProductionProductivity7类方法的所有方法。注意:这假设您省略的方法也是类方法,即以“self”开头。

当然,您可以这样创建一个模块:

module ProductionProductivity7sHelper
  def import1(file) # notice I dropped 'self.'

    ...

  end

  ...

end
然后在课堂上,添加:

class ProductionProductivity7 < ApplicationRecord
  extend ProductionProductivity7sHelper

  ...

end
class ProductionProductivity7


这将添加模块中定义为ProductionProductivity7类方法的所有方法。注意:这假设您省略的方法也是类方法,即以“self”开头。

改用服务如何?您可以建议的任何示例都必须是您的旧代码,是吗?我在您的模型中没有看到
扩展代码。(
code
似乎是个坏名字,但我想你以后会改变吗?)在Gisty上更新了所有以前的和新的代码。你只需在你的
app/models/application\u record.rb
上编写这些方法,然后从任何模型调用它,就像从任何模型实例方法调用它一样。。此外,您还可以作为任何呼叫模型的实例访问
self
。改用服务如何?您可以建议的任何示例都必须是您的旧代码,是吗?我在您的模型中没有看到
扩展代码。(
code
似乎是个坏名字,但我想你以后会改变吗?)在Gisty上更新了所有以前的和新的代码。你只需在你的
app/models/application\u record.rb
上编写这些方法,然后从任何模型调用它,就像从任何模型实例方法调用它一样。。此外,您还可以访问任何呼叫模型的实例,即
self
。我只需要一个简单的答案,我正在更新我的问题。没有那么复杂。但是,我很感激你所说的。祝你好运!我在app文件夹中添加了一个文件call Code.rb,并将我的模型的所有操作添加到其中,并在模型中进行扩展。但是获取错误错误未定义的方法“search”for#我删除了self我在控制器内部使用search。将
search
用作方法名和参数名可能会导致问题(我在猜测,还没有考虑清楚)。您可以尝试将参数更改为
search\u scope
,如上所述。此外,您可能希望遵循命名约定来匹配您的文件名和模块名。如果模块名为
FooBar
,则该文件应名为
FooBar.rb
。如果编辑问题以显示当前模块代码、调用
search
的控制器代码以及错误堆栈,可能会有所帮助。否则,调试可能发生的事情有点困难。我只想要一个简单的答案,我正在更新我的问题。没有那么复杂。但是,我很感激你所说的。祝你好运!我在app文件夹中添加了一个文件call Code.rb,并将我的模型的所有操作添加到其中,并在模型中进行扩展。但是获取错误错误未定义的方法“search”for#我删除了self我在控制器内部使用search。将
search
用作方法名和参数名可能会导致问题(我在猜测,还没有考虑清楚)。您可以尝试将参数更改为
search\u scope
,如上所述。此外,您可能希望遵循命名约定来匹配您的文件名和模块名。如果模块名为
FooBar
,则该文件应名为
FooBar.rb
。如果编辑问题以显示当前模块代码、调用
search
的控制器代码以及错误堆栈,可能会有所帮助。否则,就有点难理解了