保存之前,Ruby on Rails has_many通过关联对象 [英] Ruby on Rails has_many through association objects before save

查看:72
本文介绍了保存之前,Ruby on Rails has_many通过关联对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Ruby on Rails项目中,我试图在将所有内容保存到数据库之前访问ActiveRecord上的关联对象.

on a Ruby on Rails project I'm trying to access association objects on an ActiveRecord prior to saving everything to the database.

class Purchase < ActiveRecord::Base

  has_many :purchase_items, dependent: :destroy
  has_many :items, through: :purchase_items

  validate :item_validation

  def item_ids=(ids)
    ids.each do |item_id|
      purchase_items.build(item_id: item_id)
    end
  end

  private

  def item_validation
    items.each do |item|
      ## Lookup something with the item
      if item.check_something
        errors.add :base, "Error message"
      end
    end
  end

end

如果我像这样建立我的对象: purchase = Purchase.new(item_ids: [1, 2, 3])并尝试将其保存为item_validation方法还没有填充items集合,因此,即使已设置了项目,也没有机会在其中任何一个上调用check_something方法.

If I build out my object like so: purchase = Purchase.new(item_ids: [1, 2, 3]) and try to save it the item_validation method doesn't have the items collection populated yet, so even though items have been set set it doesn't get a chance to call the check_something method on any of them.

是否可以在持久保存我的购买模型和关联模型之前访问项目集合,以便我可以对它们进行验证?

Is it possible to access the items collection before my purchase model and association models are persisted so that I can run validations against them?

如果我将item_validation方法更改为:

def item_validation
  purchase_items.each do |purchase_item|
    item = purchase_item.item
    ## Lookup something with the item
    if item.something
       errors.add :base, "Error message"
    end
  end
end

它似乎按照我想要的方式工作,但是我很难相信,在将我的购买和相关记录保存到数据库之前,无法直接使用rails访问项目集合.

it seems to work the way I want it to, however I find it hard to believe that there is no way to directly access the items collection with rails prior to my purchase and associated records being saved to the database.

推荐答案

删除您自己的item_ids=方法-Rails会为您生成一个方法(请参见

Remove your own item_ids= method - rails generates one for you (see collection_singular_ids=ids). This might already solve your problem.

class Purchase < ActiveRecord::Base

  has_many :purchase_items, dependent: :destroy
  has_many :items, through: :purchase_items

  validate :item_validation

  private

  def item_validation
    items.each do |item|
      ## Lookup something with the item
      if item.check_something
        errors.add :base, "Error message"
      end
    end
  end

end

在我看来,看代码的第二件事是:将验证移到Item类.所以:

The second thing that comes in my mind looking at your code: Move the validation to the Item class. So:

class Purchase < ActiveRecord::Base
  has_many :purchase_items, dependent: :destroy
  has_many :items, through: :purchase_items
end

class Item < ActiveRecord::Base
  has_many :purchase_items
  has_many :purchases, through: :purchase_items

  validate :item_validation

  private

  def item_validation
      if check_something
        errors.add :base, "Error message"
      end
  end
end

如果Item之一无效,则您的Purchase记录也将无效.

Your Purchase record will also be invalid if one of the Items is invalid.

这篇关于保存之前,Ruby on Rails has_many通过关联对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆