gpt4 book ai didi

sql - Rails 4 访问连接表属性

转载 作者:行者123 更新时间:2023-12-03 10:34:26 25 4
gpt4 key购买 nike

我有一个 has_many through配方应用程序的连接表设置,其中 IngredientMeal通过 MealIngredient 连接.内MealIngredient , 我有 meal_id , ingredient_id , 和 amount .我的问题是:如何访问 amount柱子?

在我的食谱 View 中,我遍历成分:

@meal.ingredients.each do |i|

我可以访问成分的属性,但不能访问 MealIngredient 中的数量加入记录。

我尝试使用 includes在查询中做 @meal.ingredients.includes(:meal_ingredients) ,但我不确定如何访问 amount在上述循环中。当我使用 i.inspect ,我没有看到任何对 meal_ingredients 的引用表。

是否有某种方法可以使用 i.amount 访问该循环中的变量? ?

预先感谢您的任何帮助!

最佳答案

2020 年 8 月 1 日更新 - RPECK

在我们找到合适的解决方案之前,我们为此苦苦挣扎了几个月:

——

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, { -> extending: IngredientAmount }, through: :meal_ingredients
end

#app/models/concerns/ingerdient_amount.rb
module IngredientAmount

# => Load
# => Triggered whenever module is invoked (allows us to populate response data)
# => #<Method: ActiveRecord::Relation#load(&block) c:/Dev/Apps/pwinty-integration/.bundle/ruby/2.7.0/gems/activerecord-6.0.2.1/lib/active_record/relation.rb:614>
def load(&block)

# => This is called from the following reference - if you want to dig deeper, you can use method(:exec_queries).source_location
# => c:/Dev/Apps/pwinty-integration/.bundle/ruby/2.7.0/gems/activerecord-6.0.2.1/lib/active_record/association_relation.rb:42
unless loaded?
exec_queries do |record|
record.assign_attributes({amount: items[record.id]}) if items[record.id].present?
end
end

end

# Load
# Deprecated with AR 6.0
#def load
# amounts.each do |amount|
# proxy_association.target << amount
# end
#end

#Private
private

#Amounts
# Not needed after AR 6.0
#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)
through_collection.pluck(through_source_key, :amount).map{ |id, amount| { id => amount } }.inject(:merge) #-> { id: record, id: record }
end

#Target
# This no longer works with AR 6.0+
#def target_collection
# #load_target
# proxy_association.target
#end

end

这应该附加 amount归因于您的 ingredient对象,允许您执行:
@meal = Meal.find 1
@meal.ingredients.each do |ingredient|
ingredient.amount
end

关于sql - Rails 4 访问连接表属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25235025/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com