Ruby on Rails: ratyrate gem table already exists? - ruby-on-rails

I'm using rails 5, and I've installed the gem and tried to run the migration, but I'm getting this error:
Index name 'index_rates_on_rater_id' on table 'rates' already exists
Does anyone know why this exists? This is a new site and started fresh just adding devise gem.
This is the migration file that wouldn't complete on execution rails db:migrate
class CreateRates < ActiveRecord::Migration[5.1]
def self.up
create_table :rates do |t|
t.belongs_to :rater
t.belongs_to :rateable, :polymorphic => true
t.float :stars, :null => false
t.string :dimension
t.timestamps
end
add_index :rates, :rater_id
add_index :rates, [:rateable_id, :rateable_type]
end
def self.down
drop_table :rates
end
end

The gem creates a migration that does not work in later versions of rails. In Rails 5 when you use the belongs_to and references macros they create indices and foreign keys by default.
All you really need is this:
class CreateRates < ActiveRecord::Migration[5.1]
def self.change
create_table :rates do |t|
t.belongs_to :rater
t.belongs_to :rateable, polymorphic: true
t.float :stars, null: false
t.string :dimension
t.timestamps
end
add_index :rates, [:rateable_id, :rateable_type]
end
end
You don't need up and down since Rails is smart enough to know how to rollback this migration.

Related

ArgumentError: Index name ... is too long; the limit is 62 characters

I created a scaffold with this command (Rails 5.2.1.1):
rails g scaffold EmailAddress value:string:index
email_address_type:references
email_addressable:references{polymorphic}
position:integer
which resulted in this migration file:
class CreateEmailAddresses < ActiveRecord::Migration[5.2]
def change
create_table :email_addresses do |t|
t.string :value
t.references :email_address_type, foreign_key: true
t.references :email_addressable, polymorphic: true
t.integer :position
t.timestamps
end
add_index :email_addresses, :value
end
end
Unfortunately this raises the following error on rails db:migrate:
Caused by:
ArgumentError: Index name
'index_email_addresses_on_email_addressable_type_and_email_addressa...'
on table 'email_addresses' is too long; the limit is 62 characters
I understand the problem and the error. I'm wondering what the best solution is because the index is not set explicity by add_index but by some background magic.
As Wintermeyer says is one solution, there is another way at least I find smoother to use.
t.references :email_address_type, foreign_key: true,
index: { name: "addressable_index" }
Through this you dont get a bunch of add_index rows in your migration. This helps if you ever have a large migration and need to find a specific index quickly. This is just my personal opinion, Wintermeyer solution is also a working fix!
index: false is the solution for this problem. Followed by an add_index at the bottom. Here is the migration:
class CreateEmailAddresses < ActiveRecord::Migration[5.2]
def change
create_table :email_addresses do |t|
t.string :value
t.references :email_address_type, foreign_key: true
t.references :email_addressable, polymorphic: true, index: false
t.integer :position
t.timestamps
end
add_index :email_addresses, :value
add_index :email_addresses, [:email_addressable_type,
:email_addressable_id],
name: 'email_addressable_index'
end
end

"TypeError: no implicit conversion of nil into String" on HABTM association

I have to deal with this error when I try to associate a record to another one via a HABTM association:
Person.first.communities = Communities.all
Models and migrations:
class CreatePeople < ActiveRecord::Migration
def change
create_table :people do |t|
t.string :name
t.string :email
t.timestamps null: false
end
end
end
class CreateCommunities < ActiveRecord::Migration
def change
create_table :communities do |t|
t.string :name
t.text :description
t.timestamps null: false
end
end
end
class CreateJoinTablePersonCommunity < ActiveRecord::Migration
def change
create_join_table :people, :communities do |t|
# t.index [:person_id, :community_id]
# t.index [:community_id, :person_id]
end
end
end
I use the pg (0.18.4) gem with the Postgres (9.5.2)
Youcan use below code to create relationship.
Person.first.communities << Communities.all
If this not works please check your associations via reflect association method on the model.

ActiveAdmin error pushing to heroku, existing config built

When I push my rails 4 app to Heroku, I receive the following fatal rake error:
You're trying to register ActiveAdmin::Comment as Comment, but the existing ActiveAdmin::Resource config was built for Comment!
I have a Comment model which has an ActiveAdmin file like this:
# /app/admin/comment.rb
ActiveAdmin.register Comment do
end
An ActiveAdmin migration creates the following active_admin_comments table. I am wondering if this might be related to the conflict, but I am not sure.
class CreateActiveAdminComments < ActiveRecord::Migration
def self.up
create_table :active_admin_comments do |t|
t.string :namespace
t.text :body
t.string :resource_id, :null => false
t.string :resource_type, :null => false
t.references :author, :polymorphic => true
t.timestamps
end
add_index :active_admin_comments, [:namespace]
add_index :active_admin_comments, [:author_type, :author_id]
add_index :active_admin_comments, [:resource_type, :resource_id]
end
def self.down
drop_table :active_admin_comments
end
end
I did have ActiveAdmin working fine on Heroku before this, including both of the files above. I cannot think of what has changed since the last push that could affect the Comment model. Any points of direction would be greatly appreciated!

Rails: trouble understanding database relationships

So I am trying to create three models, Project, Entry and User. A Project has many Entries, and a a User has many Entries. I scaffolded the above three models with the following commands:
rails g scaffold Project title:string
rails g scaffold Entry project:project_id entry_for:user_id created_by:userid \
date:string start_time:string end_time:string total:string type_of_work:string \
on_off_site:string phase:string description:text
rails g scaffold User name:string
I realize that I probably totally goofed up the part where I manually put in the foreign keys for the other tables in the Entry model. I don't know how much has_many belongs_to automates the relationship between different models in terms of keys so I tried to add the foreign key fields manually. Is this wrong?
When I try to run db:migrate I get the following error:
undefined method `user_id' for #<ActiveRecord::ConnectionAdapters::TableDefinition:0x007fc1bdf37970>
Here are my migrations, as I tried to remove all of the foreign key fields but got the above error.
class CreateProjects < ActiveRecord::Migration
def change
create_table :projects do |t|
t.string :name
t.timestamps
end
end
end
class CreateEntries < ActiveRecord::Migration
def change
create_table :entries do |t|
t.string :project
t.string :project_id
t.user_id :entry_for
t.user_id :created_by
t.string :date
t.string :start_time
t.string :end_time
t.string :total
t.string :type_of_work
t.string :on_off_site
t.string :phase
t.text :description
t.timestamps
end
end
end
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.timestamps
end
end
end
class RemoveColumns < ActiveRecord::Migration
def self.up
remove_column :entries, :created_by
remove_column :entries, :entry_for
remove_column :entries, :project_id
end
def self.down
add_column :entries, :created_by, :user_id
add_column :entries, :entry_for , :user_id
add_column :entries, :project_id, :string
end
end
Thank you for your help!
In your migrations, instead of t.user_id you can try t.integer or t.index. That should at least get your migrations running.
I am going to use t.references entry_for and then write belongs_to :entry_for, class_name: "User" in the Entry model as a means of writing my own foreign key name. For the project column in entries I realized I can similarly write t.references project.

Do I need to create an assocation table for a :has_many :through association?

I'm trying to use a :has_many :through type association, but I'm getting the following error:
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: work_units.developer_id:
Many other posts about this sort of thing have just had spelling mistakes, but I've checked mine.
class Developer < ActiveRecord::Base
attr_accessible :skype_name, :language_ids, :user_attributes
has_many :work_units
has_many :projects, :through => :work_units
...
end
class Project < ActiveRecord::Base
attr_accessible :complete, :description, :finalised, :price
has_many :work_units
has_many :developers, :through => :work_units
...
end
class WorkUnit < ActiveRecord::Base
attr_accessible :hours_worked
belongs_to :project
belongs_to :developer
end
I've run db:migrate and it didn't complain. I did make a mistake and had to rollback the db then re-migrate, but I think I did it right. I use the annotate gem and it doesn't show any of the relationship ids I'd expect. So, do I need to create a WorkUnits table or am I missing something? The rails guide didn't mention manually making tables.
Edit
Here's the migration I used to create the WorkUnit model and stuff:
class CreateWorkUnits < ActiveRecord::Migration
def change
create_table :work_units do |t|
t.integer :hours_worked, :default => 0
t.timestamps
end
end
end
Edit 2
Snippets from my schema.rb:
create_table "work_units", :force => true do |t|
t.integer "hours_worked", :default => 0
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "projects", :force => true do |t|
t.string "description"
t.decimal "price", :precision => 8, :scale => 2
t.boolean "complete", :default => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
Similarly for :developers. So, why doesn't my migration add the association information for me?
Your WorkUnit migration should look like this:
class CreateWorkUnits < ActiveRecord::Migration
def change
create_table :work_units do |t|
t.integer :hours_worked, :default => 0
t.references :developer
t.references :project
t.timestamps
end
add_index :work_units, :developer_id
add_index :work_units, :project_id
end
end
You need to add the foreign keys to your work_units table.
class CreateWorkUnits < ActiveRecord::Migration
def change
create_table :work_units do |t|
t.integer :hours_worked, :default => 0
t.integer :project_id, null: false
t.integer :developer_id, null: false
t.timestamps
end
add_index :work_units, :project_id
add_index :work_units, :developer_id
end
end
Another way:
class CreateWorkUnits < ActiveRecord::Migration
def change
create_table :work_units do |t|
t.integer :hours_worked, :default => 0
t.belongs_to :project
t.belongs_to :developer
t.timestamps
end
add_index :work_units, :project_id
add_index :work_units, :developer_id
end
end
You can also define these fields when generating your model, then they'll be added to the migration automatically as show in the second snippet.
$ rails g model WorkUnit hours_worked:integer project:belongs_to developer:belongs_to
Hope that helps.
A table for WorkUnit needs to exist, whether that means it migration was automatically generated via scaffolding or if the migration was manually written by you.
If you don't have a migration yet that creates that table, you'll need to create that migration because the table does need to exist.
You do need a work_units table with a project_id and developer_id column.
Have a look at http://xyzpub.com/en/ruby-on-rails/3.2/activerecord_datenbank_anlegen.html if you don't know how to create a table.

Resources