I'm trying to generate 3 scaffolds:
$ rails g scaffold Artist name:string type:string bio:text resume:string
site:string
$ rails g scaffold ArtistSerie title:string artist:references
$ rails g scaffold ArtistSeriePhoto photo:string
title:string year:integer description:text dimensions:string
featured:boolean artist_serie:references
the first two models are creating their indexes and foreign keys properly, but the third one is generating this error after rake db:migrate:
Mysql2::Error: Key column 'artist_series_id' doesn't exist in table: ALTER TABLE `artist_serie_photos` ADD CONSTRAINT `fk_rails_9422e9e931`
FOREIGN KEY (`artist_series_id`)
REFERENCES `artist_series` (`id`)
here is the generated migrations:
class CreateArtists < ActiveRecord::Migration
def change
create_table :artists do |t|
t.string :name
t.string :type
t.text :bio
t.string :resume
t.string :site
t.timestamps null: false
end
end
end
class CreateArtistSeries < ActiveRecord::Migration
def change
create_table :artist_series do |t|
t.string :title
t.references :artist, index: true, foreign_key: true
t.timestamps null: false
end
end
end
class CreateArtistSeriePhotos < ActiveRecord::Migration
def change
create_table :artist_serie_photos do |t|
t.string :photo
t.string :title
t.integer :year
t.text :description
t.string :dimensions
t.boolean :featured
t.references :artist_serie, index: true, foreign_key: true
t.timestamps null: false
end
end
end
the table was created and the field artist_serie_id too but the index and foreign key don't.
I already created another blank project and it works (on sqlite) so probably it's a mysql adapter error.
Any idea?
I appreciate your help!
I expect the root problem is that series is singular. That is, serie is not the singular form of series. It might be worth replacing series with sequence.
Related
i have a problem creating a db table through rails generators.
I named a table personal_data and works fine.
class CreatePersonalData < ActiveRecord::Migration
def change
create_table :personal_data do |t|
t.string :name
t.string :lastName
t.string :dni
t.string :contact
t.references :user, index: true, foreign_key: true
t.timestamps null: false
end
end
end
But i created another table with a reference to Personal Data
class CreateMerchants < ActiveRecord::Migration
def change
create_table :merchants do |t|
t.string :storeName
t.references :personal_data, index: true, foreign_key: true
t.references :category, index: true, foreign_key: true
t.string :webPage
t.string :city
t.timestamps null: false
end
end
end
And when a run the migration instead of seeking for personal_data_id the migrations looks for personal_datum_id and throws and exception.
PG::UndefinedColumn: ERROR: no existe la columna «personal_datum_id» referida en la llave foránea
: ALTER TABLE "merchants" ADD CONSTRAINT "fk_rails_e4239c30dc"
FOREIGN KEY ("personal_datum_id")
REFERENCES "personal_data" ("id")
I translate the error to English
column "personal_datum_id" referenced in foreign key constraint does not exist
I'm not sure why it's confused, but perhaps you can set up your inflections such that the plural of personal_data is personal_data?
In the file: config/initializers/inflections.rb
ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 'personal_data', 'personal_data'
end
add self.table_name = 'personal_data' in your personal_data.rb model and run the migration
I'm trying to add new column into the table by 'rake db:migrate',but it return nothing in cmd.Then i try 'rake db:migrate:status' this time it return the following...
C:\Sites\seas>rake db:migrate:status
database: seas_development
Status Migration ID Migration Name
--------------------------------------------------
up 20160323084854 Create equipment
up 20160329072332 Devise create users
Below is inside my migration file...
class CreateEquipment < ActiveRecord::Migration
def change
create_table :equipment do |t|
t.string :name
t.string :equip_id
t.date :buy_date
t.string :brand
t.string :note
t.date :exp
t.string :status
t.string :serial
t.float :price
t.string :pic_id
t.string :ownby
t.timestamps null: false
end
add_column :equipment, :process ,:string
end
end
This only happen if there exist some data in the table,otherwise migration work fine.
Any suggestion ?
You have a typo
add_column :equipment, :process ,:string
Table name should be in plural
add_column :equipments, :process ,:string
But... if the migration had already be ran, then it will not run again. Create a new migration
rails g migration add_process_to_equipments process
rake db:migrate
Ta dah!
I'm developing my Ruby On Rails application that is using PostgreSQL as a database and I've faced a problem.
Here is my Questions table (schema.rb):
create_table "questions", primary_key: "hashid", force: :cascade do |t|
t.string "title"
t.text "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "questions", ["hashid"], name: "index_questions_on_hashid", unique: true, using: :btree
where hashid field (string) is being used instead of a default numeric id field.
Here's my migration for both Questions and Comments tables:
# Questions migration
class CreateQuestions < ActiveRecord::Migration
def change
create_table :questions, id: false do |t|
t.text :hashid, primary_key: true
t.string :title
t.text :body
t.timestamps null: false
end
add_index :questions, :hashid, unique: true
end
end
# Comments migration
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.text :body
t.references :question, foreign_key: :hashid
t.timestamps null: false
end
end
end
I want to relate Comments with Questions in my application using belongs_to and has_many relationship accordingly, but the default t.references :question is trying to relate by using id column from the target table.
Here is the migration error message:
== 20160326185658 CreateComments: migrating ===================================
-- create_table(:comments)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedColumn: ERROR: column "id" referenced in foreign key constraint does not exist
: ALTER TABLE "comments" ADD CONSTRAINT "comments_question_id_fk" FOREIGN KEY ("question_id") REFERENCES "questions"(id)
How could I relate by using other than id field? In my case it is hashid?
I would prefer to still name the primary key column id even when the column contains a random generated string.
To create a string id column in your database, use a migration like this:
create_table :questions, id: false do |t|
# primary key should not be nil, limit to improve index speed
t.string :id, limit: 36, primary: true, null: false
# other columns ...
end
In your model, ensure that a id is created:
class Question < ActiveRecord::Base
before_validation :generate_id
private
def generate_id
SecureRandom:uuid
end
end
When you are already in Rails 5 you might just want to use has_secure_token :id instead of the before_validation call back and the generate_id method.
I am creating a gem
I have a generator to create a migration based on a name of your choosing
rails g my_generator MODEL
I am not using rails'
rails g migration XYZ
But instead pretty much copying what a schema would look like...example: if a user types the following
rails g my_generator Item
You get:
class CreateItem < ActiveRecord::Migration
def change
create_table "items", force: true do |t|
t.string "title"
t.integer "color_id"
t.integer "size_id"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "base_product_id"
t.integer "stock_qty"
end
end
end
The name of the migration is (my_generator)create_items.rb I have not inserted the timestamp in the start of the migration. That is really the only difference between a rails g model Item's migration, and the one I get from my generator.
My migration doesn't do anything, but I tested creating a new model, and running rake db:migrate, the rails g model migrates, mine does not.
Here is my generator:
class Rails::ShiftedCommerceGenerator < Rails::Generators::NamedBase
def create_main_model
create_file "app/models/shifted_commerce/#{plural_name.singularize}.rb", <<-FILE
class #{class_name} < ActiveRecord::Base
belongs_to :base_#{plural_name.singularize}
has_many :line_items
belongs_to :size
belongs_to :color
validates_uniqueness_of :base_#{plural_name.singularize}_id, :scope => [:size_id]
def is_base_#{plural_name.singularize}?
return true if self.class.name == "Base#{class_name}"
end
def is_#{plural_name.singularize}?
return true if self.class.name == "#{class_name}"
end
def in_stock
self.stock_qty > 0
end
end
FILE
end
def create_main_migration
create_file "db/migrate/shifted_commerce_create_#{plural_name}.rb", <<-FILE
class Create#{class_name} < ActiveRecord::Migration
def change
create_table :#{plural_name}, force: true do |t|
t.string :title
t.integer :color_id
t.integer :size_id
t.datetime :created_at
t.datetime :updated_at
t.integer :base_product_id
t.integer :stock_qty
t.timestamps
end
end
end
FILE
end
end
Make sure you include the timestamp when you are generating your own migrations
(not using rails g migration)
Your generator should include something this:
create_file "db/migrate/#{Time.now.strftime("%Y%m%d%H%M%S")}_create_#{plural_name}.rb", <<-FILE
the .strftime method is a way to get the timestamp into your migration file the same way rails has it formatted.
I am trying to create a user_roles table in my engine that joins the user with a particular role allowing that user to have one or more roles.
I have the following migrations:
User
-- This migration works fine.
class CreateXaaronUsers < ActiveRecord::Migration
def change
create_table :xaaron_users do |t|
t.string :first_name
t.string :last_name
t.string :user_name
t.string :email
t.string :password
t.string :salt
t.timestamps
end
end
end
Roles
-- This migration works fine
class Roles < ActiveRecord::Migration
def change
create_table :xaaron_roles do |t|
t.string :role
t.timestamps
end
end
end
user_roles
-- This migration explodes stating that column user_id doesn't exist. I assume that this migration, dealing with indexes and the such, would create the appropriate columns referencing what I am telling it to reference.
class UserRolesJoin < ActiveRecord::Migration
def change
create_table :xaaron_user_roles, id: false do |t|
t.references :xaaron_user, null: false
t.references :xaaron_role, null: false
end
add_index :xaaron_user_roles, :user_id
add_index :xaaron_user_roles, [:role_id, :user_id], unique: true
add_index :xarron_roles, :role, unique: true
end
end
The exact error is:
PG::UndefinedColumn: ERROR: column "user_id" does not exist
: CREATE INDEX "index_xaaron_user_roles_on_user_id" ON "xaaron_user_roles" ("user_id")/Users/Adam/.rvm/gems/ruby-2.0.0-p353/gems/activerecord-4.0.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:128:in `async_exec'
/Users/Adam/.rvm/gems/ruby-2.0.0-p353/gems/activerecord-4.0.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:128:in `block in execute''
Did I fail at typing something? Why is this migration failing, aside from the obvious?
If you just want to create a join table then,
1. Remove the existing migration
rails d migration UserRolesJoin
2. Create a new migration for join table as
rails g migration CreateJoinTableUserRole user role
This will create a migration like:
class CreateJoinTableUserRole < ActiveRecord::Migration
def change
create_join_table :users, :roles do |t|
# t.index [:user_id, :role_id]
# t.index [:role_id, :user_id]
end
end
end
NOTE: You need to uncomment one of the combination as per your requirement from the generated migration.
3. Run rake db:migrate