我很难确定如何在rails中序列化模型的嵌套属性。我有一个RecipeTemplate,它将已存在的Recipe存储在它的template_data属性中。 Recipe有两个级别的嵌套属性。
这是在rails 3.1.0.rc4
上class RecipeTemplate < ActiveRecord::Base
serialize :template_data, Recipe
...
end
class Recipe < ActiveRecord::Base
has_many :ingredients
accepts_nested_attributes_for :ingredients
...
end
Recipe中的成分也有嵌套属性(SubIngredients)。
如果我使用如下对象设置template_data:
Recipe.includes(:ingredients => [:sub_ingredients]).find(1)
我会得到一个TypeError“无法转储匿名类Class”,这是有道理的,因为它不知道如何序列化Ingredients或SubIngredients。
如何序列化模型中的嵌套属性,以便您可以使用:
serialize :template_data, Recipe
或者我是否必须以其他方式序列化数据并自行执行类型安全检查?
提前感谢您提供任何帮助
答案 0 :(得分:1)
我可以看到为什么你希望模板本身存储在一个序列化列中,但是你需要比那种类型的列所允许的更多地存储所存储的数据。这就是我要做的事情:
应用程序/模型/ recipe_template.rb
class RecipeTemplate < ActiveRecord::Base
serialize :template_data
attr_accessible :name, :recipe
def recipe=(r)
self.template_data = r.serializable_hash_for_template
end
def recipe
Recipe.new(template_data)
end
end
应用程序/模型/ recipe.rb
class Recipe < ActiveRecord::Base
has_many :ingredients, as: :parent
accepts_nested_attributes_for :ingredients
attr_accessible :name, :ingredients_attributes
def serializable_hash_for_template(options={})
options[:except] ||= [:id, :created_at, :updated_at]
serializable_hash(options).tap do |h|
h[:ingredients_attributes] = ingredients.map(&:serializable_hash_for_template)
end
end
end
应用程序/模型/ ingredient.rb
class Ingredient < ActiveRecord::Base
belongs_to :parent, polymorphic: true
has_many :sub_ingredients, class_name: 'Ingredient', as: :parent
accepts_nested_attributes_for :sub_ingredients
attr_accessible :name, :sub_ingredients_attributes
def serializable_hash_for_template(options={})
options[:except] ||= [:id, :parent_id, :parent_type, :created_at, :updated_at]
serializable_hash(options).tap do |h|
h[:sub_ingredients_attributes] = sub_ingredients.map(&:serializable_hash_for_template)
end
end
end
然后创建并使用模板:
# create a recipe to use as a template
taco_meat = Ingredient.create(name: "Taco Meat")
taco_seasoning = taco_meat.sub_ingredients.create(name: "Taco Seasoning")
sams_tacos = Recipe.create(name: "Sam's Tacos")
sams_tacos.ingredients << taco_meat
# create a template from the recipe
taco_recipe = RecipeTemplate.create(name: "Taco Recipe", recipe: sams_tacos)
# build a new recipe from the template
another_taco_recipe = taco_recipe.recipe
不同之处在于您使用序列化列来存储要在Recipe构造函数中使用的Hash。如果你只想序列化对象,其他海报是正确的 - 只需关联一个对象。
答案 1 :(得分:-2)
为什么不在RecipeTemplate模型中使用标签recipe_id
并将其链接到配方而不是尝试序列化配方对象?