【问题标题】:Rails create a method accessible via both the model and controllerRails 创建了一个可通过模型和控制器访问的方法
【发布时间】:2014-02-28 08:11:20
【问题描述】:

无论如何创建一个我可以在模型和控制器中调用的函数?我有一个函数可以抓取一组文件并剥离扩展名并希望针对列表进行验证。但是我也想在控制器中访问这个列表,这样我就可以输出一个选项的选择框。我目前有这个,但是 VALID_MODULES 并没有一直被填充。

class Job < ActiveRecord::Base

  after_initialize :init
  VALID_MODULES =[];

  validates :name, presence: true
  validates :desc, presence: true
  validates :api, presence: true, :inclusion => { :in => VALID_MODULES}
  validates :filters, presence: true
  validates :toe, presence: true

  def init
    Dir.foreach('lib/resources') do |item|
         next if item == '.' or item == '..' or item == 'resource.rb'
            #Wont be called very often so O(n) complexity is fine (small #elements)
            VALID_MODULES.push(item[0..-4]) unless VALID_MODULES.include?(item[0..-4])
    end
  end

end

【问题讨论】:

  • 几件事。 1) 这些模块是特定于 Job 类的吗?它们是否特定于工作实例?还是它们对应用程序是全局的 2)您也不希望在初始化时执行此功能,因为这将为您从数据库中提取的每条记录执行,并且成本非常高。这些问题的答案会影响正确的解决方案。
  • Peter,valid_modules 对应用程序来说确实是全局的。是的,我认为,这是我能够使用这些值作为验证并能够在控制器中访问它的唯一方法。

标签: ruby-on-rails ruby


【解决方案1】:

不要使用常量 (VALID_MODULES),而是尝试将其作为 job 的属性。

class Job < ActiveRecord::Base

  attr_accessor :valid_modules
  after_initialize :init


  validates :name, presence: true
  validates :desc, presence: true
  validates :api, presence: true, :inclusion => { :in => VALID_MODULES}
  validates :filters, presence: true
  validates :toe, presence: true

  def init
    @valid_modules ||= []
    Dir.foreach('lib/resources') do |item|
         next if ['.', '..', 'resource.rb'].include?(item)
         #Wont be called very often so O(n) complexity is fine (small #elements)
         @valid_modules << item[0..-4] unless @valid_modules.include?(item[0..-4])
    end
  end

end

现在在您的控制器中,您只需在您的 Job 对象上调用 valid_modules 即可返回数组。 示例:

job = Job.new
job.valid_modules

【讨论】:

    【解决方案2】:
    # in config/initializers/api_modules.rb
    module ApiModules
      def self.modules
        # the Dir[""] glob syntax here I believe exclude dot directories
        # but I still like the Array#include? syntax here for your exclusions list
        # you may need to massage the strings of your file list to be more appropriate to your case
        @modules ||= Dir["lib/*"].select{|f| !["resource.rb"].include?(f) } 
      end
    end
    
    #app/models/job.rb
    validates :api, presence: true, :inclusion => { :in => ApiModules.modules}
    

    【讨论】:

    • 至少我会这样写。 ValidModules 对用例来说有点难以描述。从您的代码看来,一项工作需要保存一个有效的 api 模块,那么为什么不将其称为 ApiModule 呢? :)
    猜你喜欢
    • 2022-08-15
    • 1970-01-01
    • 2014-09-24
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    • 2011-10-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多