0

I'm developing a Shopify App and I'm trying to create a relationship in my database where I have a Shop model and an Address model, and one shop can have different addresses and every address is related to one shop.

So I have this:

models/shop.rb

class Shop < ActiveRecord::Base
  include ShopifyApp::SessionStorage
  has_many :addresses
end

models/address.rb

class Address < ApplicationRecord
    belongs_to :shop
end

db/migrate/create_shops.rb

class CreateShops < ActiveRecord::Migration[5.1]
    has_many :addresses
  def self.up
    create_table :shops  do |t|
      t.string :shopify_domain, null: false
      t.string :shopify_token, null: false
      t.timestamps
    end

    add_index :shops, :shopify_domain, unique: true
  end

  def self.down
    drop_table :shops
  end
end

db/migrate/create_shops.rb

class CreateAddresses < ActiveRecord::Migration[5.1]
  def change
    create_table :addresses do |t|
      t.text :Address1
      t.text :Address2
      t.string :Postal
      t.string :Phone
      t.string :City

      t.timestamps
    end
  end
end

I think I don't have this well... So, how can I add addresses to a shop in my database?

Thank you.

Gyntonic
  • 346
  • 2
  • 4
  • 14

1 Answers1

0

I think here:

class CreateShops < ActiveRecord::Migration[5.1]
  has_many :addresses
  def self.up
    create_table :shops  do |t|
      t.string :shopify_domain, null: false
      t.string :shopify_token, null: false
      t.timestamps
    end

    add_index :shops, :shopify_domain, unique: true
  end

  def self.down
    drop_table :shops
  end
end

you do not want has_many :addresses. And this:

class CreateAddresses < ActiveRecord::Migration[5.1]
  def change
    create_table :addresses do |t|
      t.text :Address1
      t.text :Address2
      t.string :Postal
      t.string :Phone
      t.string :City

      t.timestamps
    end
  end
end

should be like this:

class CreateAddresses < ActiveRecord::Migration[5.1]
  def change
    create_table    :addresses do |t|
      t.references  :shop
      t.string      :address_1
      t.string      :address_2
      t.string      :postal
      t.string      :phone
      t.string      :city

      t.timestamps
    end
  end
end

As mentioned by @engineersmnky in the comments, as of Rails 5, an index is automatically created on the foreign key.

For future readers who may not be on Rails 5 (or later, depending on how far into the future you are) who want to add an index to the foreign key...

If you're on Rails 4.x, then do:

class CreateAddresses < ActiveRecord::Migration
  def change
    create_table    :addresses do |t|
      t.references  :shop, index: true
      t.string      :address_1
      t.string      :address_2
      t.string      :postal
      t.string      :phone
      t.string      :city

      t.timestamps
    end
  end
end

If you're earlier than Rails 4.x, then see this question and answer.

engineersmnky
  • 25,495
  • 2
  • 36
  • 52
jvillian
  • 19,953
  • 5
  • 31
  • 44
  • 1
    `string` is probably sufficient for an address line as well unless you know someone with a 4000+ character address – engineersmnky Nov 30 '17 at 20:58
  • Ha! Good catch. I wasn't even paying attention to the field type for the other fields (my bad). Thanks! – jvillian Nov 30 '17 at 20:59
  • Also `references` adds the index by default so the second example is redundant – engineersmnky Nov 30 '17 at 21:00
  • @engineersmnky - Out of curiosity, is that new to Rails 5? I was looking at the [apidock](https://apidock.com/rails/ActiveRecord/ConnectionAdapters/Table/references) for Rails 4.2.7 and it didn't *seem* to indicate that the index was added by default. Naturally, I may have misunderstood. I'm not on Rails 5 yet, so I'm missing on some of the new stuff. – jvillian Nov 30 '17 at 21:04
  • Indeed it is [Docs for 4.2.7](https://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_reference) and [Docs for 5.X](http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-add_reference) – engineersmnky Nov 30 '17 at 21:07
  • Thanks! (I should have looked it up myself. Sorry.) Guess I'll have to get modern one of these days. – jvillian Nov 30 '17 at 21:08
  • 1
    We still have 1.9.3 rails 3 applications rolling around :) – engineersmnky Nov 30 '17 at 21:09