简体   繁体   中英

Rails HABTM :through

I have products in 3 different stores.. All stores may have the same products but the inventory can be different and so is the price.. I thought BABTM through would be the best solution

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

I am trying to create a console script which preloads everything using a restfull api. one for each store which has been predefined in the stores table. These scripts will eventually be run every day to catch all changes so besides creating new products in association with a store it should also be able to find and update them. I can't get it to work

#!/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()

If I run a similar script for another store it will update store_products even though it should be a new one. Another try

#!/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()

Please help?

this works.. I am a happy camper. It will create and or update joined/associated tables with attributes as well

#!/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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM