Jus*_*tin 25 sql ruby-on-rails ruby-on-rails-4
我有一个has_many through
连接表设置为配方应用程序在哪里Ingredient
和Meal
连接MealIngredient
.在MealIngredient
,我有meal_id
,ingredient_id
和amount
.我的问题是:我如何访问该amount
列?
在我的食谱视图中,我遍历了各种成分:
@meal.ingredients.each do |i|
Run Code Online (Sandbox Code Playgroud)
我可以访问成分的属性,但不能访问MealIngredient
连接记录中的金额.
我尝试includes
在查询中使用@meal.ingredients.includes(:meal_ingredients)
,但我不确定如何访问amount
前面提到的循环.当我使用时i.inspect
,我根本看不到任何对该meal_ingredients
表的引用.
是否有某种方法可以使用该循环访问变量i.amount
?
预先感谢您的任何帮助!
jvn*_*ill 27
在这种情况下,您应该遍历meal_ingredients
关联.您应该急切加载ingredients
关联以减少数据库查询.
@meal.meal_ingredients.includes(:ingredient).each do |meal_ingredient|
puts meal_ingredient.amount
puts meal_ingredient.ingredient.name
end
Run Code Online (Sandbox Code Playgroud)
UPDATE
这次更新是在Rich Peck回答之后发生的,但我认为有一种更简单的方法可以实现他的目标.
@meal.ingredients.select('ingredients.*, meal_ingredients.amount').each do |ingredient|
puts ingredient.amount
puts ingredient.name
end
Run Code Online (Sandbox Code Playgroud)
Ric*_*eck 27
啊,这个古老的how do I access my extra join table attributes
问题.我们为MONTHS苦苦挣扎,直到我们提出解决方案
-
ActiveRecord Association Extensions
你遇到的问题是Rails只会使用foreign_keys
你的连接表来加载你需要的关联数据.除非您实际直接加载连接模型,否则它将无法访问连接属性
一些觅食引导我们ActiveRecord Association Extensions
- 一种在不同的ActiveRecord关联之间访问中间数据的方法(使用一个名为的集合proxy_association
).这将允许您从连接模型访问额外属性,将它们附加到"原始"模型:
#app/models/ingredient.rb
class Ingredient < ActiveRecord::Base
attr_accessor :amount #-> need a setter/getter
end
#app/models/meal.rb
class Meal < ActiveRecord::Base
has_many :meal_ingredients
has_many :ingredients, through: :meal_ingredients, extend: IngredientAmount
end
#app/models/concerns/ingerdient_amount.rb
module IngredientAmount
#Load
def load
amounts.each do |amount|
proxy_association.target << amount
end
end
#Private
private
#Amounts
def amounts
return_array = []
through_collection.each_with_index do |through,i|
associate = through.send(reflection_name)
associate.assign_attributes({amount: items[i]}) if items[i].present?
return_array.concat Array.new(1).fill( associate )
end
return_array
end
#######################
# Variables #
#######################
#Association
def reflection_name
proxy_association.source_reflection.name
end
#Foreign Key
def through_source_key
proxy_association.reflection.source_reflection.foreign_key
end
#Primary Key
def through_primary_key
proxy_association.reflection.through_reflection.active_record_primary_key
end
#Through Name
def through_name
proxy_association.reflection.through_reflection.name
end
#Through
def through_collection
proxy_association.owner.send through_name
end
#Captions
def items
through_collection.map(&:amount)
end
#Target
def target_collection
#load_target
proxy_association.target
end
end
Run Code Online (Sandbox Code Playgroud)
这应该立即将amount
属性附加到您的ingredient
对象,允许您执行:
@meal = Meal.find 1
@meal.ingredients.each do |ingredient|
ingredient.amount
end
Run Code Online (Sandbox Code Playgroud)