Rails HABTM:通过

Posted

技术标签:

【中文标题】Rails HABTM:通过【英文标题】:Rails HABTM :through 【发布时间】:2019-11-29 17:20:51 【问题描述】:

我在 3 家不同的商店有产品。所有商店可能都有相同的产品,但库存可能不同,价格也可能不同。我认为 BABTM through 将是最好的解决方案

class Product < ApplicationRecord
  has_many :store_products
  has_many :stores, through: :store_products
end
class StoreProduct < ApplicationRecord
  belongs_to :store
  belongs_to :product
end
class Store < ApplicationRecord
  has_many :store_products
  has_many :products, through: :store_products
end

我正在尝试创建一个控制台脚本,该脚本使用 restfull api 预加载所有内容。对于已在 stores 表中预定义的每个商店一个。这些脚本最终将每天运行以捕获所有更改,因此除了创建与商店关联的新产品外,它还应该能够找到和更新它们。我无法让它工作

#!/usr/bin/env ruby
ENV['RAILS_ENV'] = ARGV.first || ENV['RAILS_ENV'] || 'development'
require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")

  def perform()
    @storeapi   = StoreApi.new
    inventory   = JSON.parse(@storeapi.get_products.body)['data']
    inventory.each do | item |
      sku                     = item['item']['no']
      @item                   = Product.where(sku: sku).first_or_initialize
      @item.weight            = nil
      @item.width             = nil
      @item.depth             = nil
      @item.length            = nil
      unless @item.stores.exists?(name: 'Storename1')
        @item.stores         << Store.where(name: 'Storename1').first
      end
      @item.store_products.update(
        status:             status,
        uid:                item['inventory_id'],
        name:               item['item']['name'],
        quantity:           item['quantity'],
        price:              item['unit_price'],
        data:               item.to_json
      )
      @item.save
    end
  end

perform()

如果我为另一家商店运行类似的脚本,它将更新 store_products,即使它应该是新的。再试一次

#!/usr/bin/env ruby
ENV['RAILS_ENV'] = ARGV.first || ENV['RAILS_ENV'] || 'development'
require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")

  def perform()
    @magento  = Magento.new
    arg       = 'searchCriteria[page_size]': "10" 
    inventory = @magento.get_products(arg)[:items]
    inventory.each do | item |
      store                   = Store.where(name: 'Storename2').first
      item[:custom_attributes]= Hash[item[:custom_attributes].collect|a| [a[:attribute_code].to_sym, a[:value]]]
      item[:stock]            = @magento.get_stockitems(item[:sku])
      sku                     = item[:sku]

      @product                = Product.where(sku: sku).first_or_initialize
      @product.ean            = item[:custom_attributes][:bf_ean]
      @product.weight         = item[:custom_attributes][:bf_weight]
      @product.width          = item[:custom_attributes][:bf_width]
      @product.depth          = item[:custom_attributes][:bf_depth]
      @product.length         = item[:custom_attributes][:bf_length]
      @product.save
      @store_product = StoreProduct.create(
        product:            @product,
        store:              store,
        status:             status,
        uid:                item[:id],
        name:               item[:name],
        quantity:           item[:stock][:quantity],
        price:              item[:price],
        data:               item.to_json
      )
      @store_product.save
    end
  end
perform()

请帮忙?

【问题讨论】:

【参考方案1】:

这行得通。我是一个快乐的露营者。它还将创建和/或更新具有属性的连接/关联表

#!/usr/bin/env ruby
ENV['RAILS_ENV'] = ARGV.first || ENV['RAILS_ENV'] || 'development'
require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")

  def perform()
    @magento  = Magento.new
    inventory = @magento.get_products()[:items]
    inventory.each do | item |

# define store
      @s = Store.where(name: 'Brickfever').first

# define product
      @p = Product.where(sku: sku).first_or_initialize
      @p.update(status:       status,
                ean:          item[:custom_attributes][:bf_ean],
...
                length:       item[:custom_attributes][:bf_length],
               )
# define join table
      @sp = StoreProduct.where(store: @s, product: @p).first_or_initialize
      @sp.update(status:             status,
                 uid:                item[:id],
...
                 data:               item.to_json
                )
    end
  end
perform()

【讨论】:

以上是关于Rails HABTM:通过的主要内容,如果未能解决你的问题,请参考以下文章

Rails 3.1 Ransack HABTM

Rails,Ransack:如何在 HABTM 关系中搜索“所有”匹配项而不是“任何”匹配项

使用 HABTM 关系更新复选框的值——Rails

Rails:在 HABTM 关系中将子项从大型记录集添加到父模型的 UI

Rails 搜索 HABTM 关系中的关联模型

Rails中使用的HABTM关系MySQL表