【问题标题】:Rails 3 - Association validation in the controller?Rails 3 - 控制器中的关联验证?
【发布时间】:2013-03-14 00:14:48
【问题描述】:

我有一个带有用户模型、信用卡模型和付款模型的 Rails 3 程序。 User has_many CreditCards,CreditCard has_many Payments。

在我的应用程序中,当用户进行新的付款时,他会从他的信用卡列表中选择他想使用哪个信用卡来付款。我想在代码中添加一个额外的验证,以确保提交给 Payment.create() 函数的 credit_card_id 实际上是当前用户拥有的。

感觉验证必须在控制器中进行,对吧?或者是否有处理这种情况的最佳做法?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 associations


    【解决方案1】:

    添加付款验证。付款很可能通过belongs_to 与用户相关联,因此我建议添加以下验证

    # payment.rb
    belongs_to :user
    validate :validates_credit_card_belongs_to_user
    
    private
    
    def validates_credit_card_belongs_to_user
      unless user.credit_card.where(id: credit_card_id).exists?
        errors.add(:credit_card_id, 'is not owned by this user')
      end
    end
    

    【讨论】:

      【解决方案2】:

      您肯定希望在您的模型中进行此验证。保留controllers skinny 并拥有胖模型通常被认为是 Rails 最佳实践。

      假设付款属于用户并且付款属于信用卡(我假设这是因为您的付款上有一个 credit_card_id 字段)您可以这样做。

      Class Payment < ActiveRecord::Base    
        belongs_to :user
        belongs_to :credit_card
      
        validate :credit_card_belongs_to_user
      
        def credit_card_belongs_to_user
          errors.add(:credit_card, 'does not belong to you') unless user == credit_card.user
        end
      end 
      

      【讨论】:

        【解决方案3】:

        您还可以在 PaymentsController 中 [在前置过滤器中] 获取这样的信用卡

        @credit_card = current_user.credit_cards.find(params[:credit_card_id])

        然后

        @payment = @credit_card.payments.build(params[:payment])

        这样您就可以确定它是 current_user 拥有的 credit_card。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-11-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-27
          • 1970-01-01
          • 1970-01-01
          • 2014-10-24
          相关资源
          最近更新 更多