0

I trying to create this enter image description here

Where User is a one to many for IncomePicture and ExpensePicture and ExpensePicture and IncomePicture have a one to one relationship to IncomeText and ExpenseText. This is what I have so far. I'm a bit confused on what migration actually does? My guess is that it updates the tables in the database. I feel that I am missing a lot in my migrations to create the desired scheme in my database. I think my models are okay but I'm not quite sure. I get confused with the rails g migration ... commands. It seems like that command updates or alters the table columns

Models:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :rememberable, :validatable

  has_many :expense_pictures 
  has_many :income_pictures

end

class IncomePicture < ActiveRecord::Base
  belongs_to :user
  mount_uploader :image, ImageUploader
  has_one :income_text
end

class IncomeText < ActiveRecord::Base
  belongs_to :income_pictures
end

class ExpensePicture < ActiveRecord::Base

  belongs_to :user
  mount_uploader :image, ImageUploader
  has_one :expense_text
end

class ExpenseText < ActiveRecord::Base
  belongs_to :expense_pictures
end

Migration

class DeviseCreateUsers < ActiveRecord::Migration
  def change
    create_table(:users) do |t|
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""
      t.datetime :remember_created_at
      t.timestamps
    end

    add_index :users, :email,                unique: true
  end
end


class CreateExpensePictures < ActiveRecord::Migration
  def change
    create_table :expense_pictures do |t|
      t.timestamps
    end
  end
end


class CreateIncomePictures < ActiveRecord::Migration
  def change
    create_table :income_pictures do |t|

      t.timestamps
    end
  end
end


class AddImageToExpensePicture < ActiveRecord::Migration
  def change
    add_column :expense_pictures, :image, :string
  end
end


class AddImageToIncomePicture < ActiveRecord::Migration
  def change
    add_column :income_pictures, :image, :string
  end
end


class CreateIncomeTexts < ActiveRecord::Migration
  def change
    create_table :income_texts do |t|
      t.timestamps
    end
  end
end


class CreateExpenseTexts < ActiveRecord::Migration
  def change
    create_table :expense_texts do |t|
      t.timestamps
    end
  end
end
1
  • You should be adding the respected FKs to the tables. Commented Jul 20, 2014 at 9:47

1 Answer 1

1

The only thing you need to add via a migration is the foreign keys. Rails will be responsible for the associations so it'll all work after that.

class AddForeignKeysToTables < ActiveRecord::Migration
  def change
    add_column :income_pictures, :user_id, :integer
    add_column :expense_pictures, :user_id, :integer
    add_column :expense_texts, :expense_picture_id, :integer
    add_column :income_texts, :income_picture_id, :integer
  end
end

You can also do it as...

add_reference :products, :user, index: true

class AddForeignKeysToTables < ActiveRecord::Migration
  def change
    add_reference :income_pictures, :user
    add_reference :expense_pictures, :user
    add_reference :expense_texts, :expense_picture
    add_reference :income_texts, :income_picture
  end
end

and in fact you can add an index to the foreign keys...

add_reference :income_pictures, :user, index: true
Sign up to request clarification or add additional context in comments.

3 Comments

No, sorry, that's not right. create_table :user do |t| t.references :expense_pictures end ... that creates a link :expense_picture_id inside the users table which is not where it's needed... Remember one user can point to MANY expense_pictures... the foreign keys need to be on the "belongs_to" side.
Edited my comment, sorry... premature 'Enter'. :)
Edited my answer to show use of add_reference instead of add_column... but the two peform equivalent actions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.