Reputation: 9229
I have a rails app set up with a many-to-many relationship between users
and widgets
. "Users" has been generated and managed through the devise
gem. When I click on create new widget, when logged in as a user, I get the error:
ActiveRecord::StatementInvalid in WidgetsController#create
Could not find table 'users_widgets'
My migration files are as follows:
class CreateWidgets < ActiveRecord::Migration
def change
create_table :widgets do |t|
t.string :name
t.timestamps null: false
end
end
create_table :users_widgets, id: false do |t|
t.belongs_to :user, index: true
t.belongs_to :widget, index: true
end
end
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
#other devise stuff...
end
end
and my widget_controller
:
def create
@user = current_user
@widget = @user.widgets.build(widget_params)
respond_to do |format|
if @widget.save
format.html { redirect_to @widget, notice: 'Widget was successfully created.' }
format.json { render :show, status: :created, location: @widget }
else
format.html { render :new }
format.json { render json: @widget.errors, status: :unprocessable_entity }
end
end
end
What have I done wrong / what is causing this error? I would have thought the definition in the createWidgets class was enough?
I hve changed my create_widgets migration file to this:
class CreateWidgets < ActiveRecord::Migration
def change
create_table :widgets do |t|
t.string :name
t.timestamps null: false
end
create_table :users_widgets, id: false do |t|
t.belongs_to :user, index: true
t.belongs_to :widget, index: true
end
end
end
and run:
$rake db:reset
$rake db:migrate
but I still get the same error...
Upvotes: 0
Views: 2304
Reputation: 20263
When you're confident that your migrations are correct yet you still have these problems, it can (sometimes) be due to the fact that previous, failed migrations have left the dB in a state that is hard to debug and/or correct.
In these instances, I often do:
$ rake db:drop # completely removes the database
$ rake db:create # creates a new, empty database
$ rake db:migrate # builds your tables
$ rake db:test:prepare # prepares your test database
Upvotes: 3
Reputation: 6438
Fix your CreateWidgets
migration as follows:
class CreateWidgets < ActiveRecord::Migration
def change
create_table :widgets do |t|
t.string :name
t.timestamps null: false
end
create_table :users_widgets, id: false do |t|
t.belongs_to :user, index: true
t.belongs_to :widget, index: true
end
end
end
Both create_table
statements have to go with in change
, not outside.
Also did you add the create_table
for users_widgets
before or after running the CreateWidgets
migration?
If you have added it after running the migration, then you need to either run bundle exec rake db:migrate:redo
or run bundle exec rake db:migrate:rollback
and then bundle exec rake db:migrate
. Essentially you need to ensure that this migration has created both the tables. You may need to add STEP
parameter while running these tasks.
Refer to Active Record Migrations for more info.
Upvotes: 1