【问题标题】:Set variable in application_controller and access in model在 application_controller 中设置变量并在模型中访问
【发布时间】:2018-07-01 03:09:25
【问题描述】:

在我的应用程序控制器中,我根据地理位置设置了一个货币变量:

class ApplicationController < ActionController::Base

  before_action :currency

  protected

  def currency
    cookies[:country] ||= request.location.country
    case cookies[:country]
    when "MY"
      c = "MYR"
    when "SG"
      c = "SGD"
    else
      c = "USD"
    end
    @currency = Currency.find_by(name: c)
  end
end

我有带有定价方法和多种货币、多种价格的模型产品,即:一种产品可以有多种货币和自定义定价。

class Product < ApplicationRecord
  has_many :prices
  has_many :currencies, through: :prices

  def price
    # how to access @currency?
  end

end

class Price < ApplicationRecord
  belongs_to :product
  belongs_to :currency
end

class Currency < ApplicationRecord
  has_many :prices
  has_many :products, through: :prices
end

在 Model Product.price 中访问 @currency 的最佳方式是什么?或者我怎样才能告诉方法只在@currency 中返回价格?这可能不是最好的处理方式,所以请指教。

【问题讨论】:

  • 我相信this 可能会对你有所帮助

标签: ruby-on-rails


【解决方案1】:

你的事情有点倒退,所以你试图解决错误的问题。模型不应该试图从控制器层获取信息,控制器应该将该信息发送到模型中:

class Product < ApplicationRecord
  #...
  def price_in(currency)
    # Access the associations however you need to and handle missing
    # information however fits your application in here...
  end
end

然后在你的控制器或视图中:

price = product.price_in(@currency)

您应该能够从任何地方(控制器、rake 任务、作业、控制台等)调用模型上的方法,而不必担心所有特定于请求的状态。

【讨论】:

    【解决方案2】:

    你不应该。你这样做违反了很多设计原则,而且你只会让自己在路上感到沮丧。

    您的模型不应该关心控制器的上下文。它应该只关心与自身相关的数据。

    不过,您可以做的是使用ActiveModel::Attributes API。

    在您的模型中:

    class Product < ApplicationRecord
      has_many :prices
      has_many :currencies, through: :prices
    
      attribute :currency 
    
      def price
        self.currency 
      end
    
    end
    

    在您的控制器中:

    class ProductsController < ApplicationController
      def show
        @product = Product.find(params[:id])
        @product.currency = @currency 
      end 
    end
    

    您可以使用ActiveModel::Attributes API 执行更多操作,例如设置默认值、运行验证,甚至设置对象的类型(布尔/真/假、整数、字符串等)——它的行为就像您在模型上的常规属性一样,它们只是没有您的数据库支持。

    关于这个伟大的 API 的更多信息https://apidock.com/rails/ActiveRecord/Attributes/ClassMethods/attribute

    【讨论】:

      【解决方案3】:

      查看this answer,了解如何访问模型中的 cookie。但是您应该考虑将此方法移出控制器并移到 Currency 类中,这似乎是一个更合乎逻辑的地方。然后,您可以将 Product 类中的方法称为 Currency.get_currency,例如。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-16
        • 1970-01-01
        • 1970-01-01
        • 2013-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多