복붙노트

[SQL] 4 액세스 표 속성을 가입 난간

SQL

4 액세스 표 속성을 가입 난간

나는 성분과 식사 MealIngredient를 통해 연결 레시피 앱 테이블 설정 가입을 통해 has_many 있습니다. MealIngredient 내에서, 나는 meal_id, ingredient_id 및 금액을 가지고있다. 내 질문은 : 나는 양의 열을 액세스 할 수 있습니까?

내 래서 피보기에서, 재료를 통해 I 루프 :

@meal.ingredients.each do |i|

나는 기록을 조인 MealIngredient에서 성분의 특성이 아닌 양에 액세스 할 수 있습니다.

내가 사용이 meal.ingredients.includes @하고 쿼리에 포함 시도 (: meal_ingredients),하지만 난 전술 루프 내 양을 액세스하는 방법을 확실 해요. 내가 i.inspect를 사용할 때, 나는 모두의 meal_ingredients 테이블에 대한 참조를 볼 수 없습니다.

i.amount를 사용하여 해당 루프 내에서 변수에 액세스 할 수있는 방법이 있습니까?

사전에 어떤 도움을 주셔서 감사합니다!

해결법

  1. ==============================

    1.2020년 8월 1일에 업데이트 - RPECK

    2020년 8월 1일에 업데이트 - RPECK

    우리는 적절한 해결책을 발견 할 때까지 몇 달 동안이 고생 :

    --

    액티브 협회 확장

    당신이 가진 문제는 레일은 당신이 필요로하는 연관 데이터를로드하기 위해 가입 테이블에서 foreign_keys을 사용하는 것입니다. 실제로 직접 모델을 결합로드하지 않는 한, 당신에게이 특성을 가입에 액세스 할 수있는 기능을 제공하지 않습니다

    일부 꼴은 액티브 협회 확장에 우리를 인도 - 방법을 액세스 중간 데이터를 다른 액티브 협회 사이에 (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
    

    이것은 당신이 수행 할 수 있도록, 지금 성분 객체에 양 속성을 추가한다 :

    @meal = Meal.find 1
    @meal.ingredients.each do |ingredient|
       ingredient.amount
    end
    
  2. ==============================

    2.이 경우, meal_ingredients 협회를 통해 당신이해야 루프. 당신은 열망 부하 재료 협회는 DB 쿼리를 줄일 수 있습니다.

    이 경우, meal_ingredients 협회를 통해 당신이해야 루프. 당신은 열망 부하 재료 협회는 DB 쿼리를 줄일 수 있습니다.

    @meal.meal_ingredients.includes(:ingredient).each do |meal_ingredient|
      puts meal_ingredient.amount
      puts meal_ingredient.ingredient.name
    end
    

    최신 정보

    이 업데이트는 리치 펙의 대답 후 왔지만 나는 그가 한 일을 달성 할 수있는 간단한 방법이 있다고 생각.

    @meal.ingredients.select('ingredients.*, meal_ingredients.amount').each do |ingredient|
      puts ingredient.amount
      puts ingredient.name
    end
    
  3. from https://stackoverflow.com/questions/25235025/rails-4-accessing-join-table-attributes by cc-by-sa and MIT license