I'm trying to rename a column that is definitely there in the schema and all the info is there, but when I go to update it it's giving me a "missing column" error and I can't figure out why? Any ideas?
Migration:
class ChangeColumnName < ActiveRecord::Migration
def change
rename_column :postcodes, :type, :zip_type
end
end
schema.rb
create_table "postcodes", force: true do |t|
t.string "postalcode"
t.string "type"
t.string "primary_city"
t.string "state"
t.string "county"
t.string "timezone"
t.string "area_code"
t.string "latitude"
t.string "longitude"
t.string "estimated_population"
t.datetime "created_at"
t.datetime "updated_at"
end
Error:
DL is deprecated, please use Fiddle
DL is deprecated, please use Fiddle
== 20150304172437 ChangeColumnName: migrating =================================
-- rename_column(:postcodes, :type, :zip_type)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
Missing column postcodes.typeC:/Users/Steve Q/Documents/GitHub/project1/db/migrate/20150304172437_change_column_name.rb:3:in `change'C:in `migrate' ActiveRecord::ActiveRecordError: Missing column postcodes.type
I have tried renaming type column to zip_type its working. Another solution is you can delete type column and add new column as zip_type.
Related
I am doing an online course , and I am trying to design a website with a user database . I have built a " Contact Us" page with a form/table .
I cannot make the timestamps show in the rails console $ Contact.all
this is my Schema.rb :
ActiveRecord::Schema.define(version: 20190518115940) do
create_table "contacts", force: :cascade do |t|
t.string "name"
t.string "email"
t.text "comments"
end
end
And this is the crate_contacts.rb file :
class CreateContacts < ActiveRecord::Migration[5.0]
def change
create_table :contacts do |t|
t.string :name
t.string :email
t.text :comments
t.timestamps
end
end
end
Your schema.rb knows nothing about timestamps. Did you created the table without timestamps and then you added it to the migration?
If so, you can rerun the migration (assuming it is the last one) with the command rails db:migrate:redo, but all the data in that table will be wiped.
Refer to this guide for further options.
when I run the rails server, localhost displays this error:
ActiveRecord::PendingMigrationError (Migrations are pending.
To resolve this issue, run: bin/rake db:migrate RAILS_ENV=development):
I have run the bin/rake... and the next error says:
$ bundle exec bin/rake db:migrate RAILS_ENV=development
== 20150225172130 CreateVotes:
migrating ======================================
-- create_table(:votes)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: table "votes" already exists: CREATE TABLE "votes"
("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "value" varchar(255),
"user_id" integer, "post_id" integer, "created_at" datetime, "updated_at"
datetime)
_create_votes.rb
class CreateVotes < ActiveRecord::Migration
def change
create_table :votes do |t|
t.string :value
t.references :user, index: true
t.references :post, index: true
t.timestamps
end
end
end
Basically, it tells me I have migrations pending, but when I attempt to migrate it says the table already exists.
20150225172130 CreateVotes:
migrating ======================================
-- create_table(:votes)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: table "votes" already exists: CREATE TABLE "votes"...
after running db:drop:all
db:create
db:migrate
db:test:clone
votes are now showing up in schema.rb:
ActiveRecord::Schema.define(version: 20150101200224) do
create_table "comments", force: true do |t|
t.text "body"
t.integer "post_id"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "comments", ["post_id"], name: "index_comments_on_post_id"
create_table "posts", force: true do |t|
t.string "title"
t.text "body"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", force: true do |t|
t.string "name"
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name:"index_users_on_reset_password_token", unique: true
create_table "votes", force: true do |t|
t.integer "value"
t.integer "user_id"
t.integer "post_id"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "votes", ["post_id"], name: "index_votes_on_post_id"
add_index "votes", ["user_id"], name: "index_votes_on_user_id"
end
model/vote.rb
class Vote < ActiveRecord::Base
belongs_to :user
belongs_to :post
end
You could do this:
class CreateVotes < ActiveRecord::Migration
def change
unless table_exists? :votes
create_table :votes do |t|
t.string :value
t.references :user, index: true
t.references :post, index: true
t.timestamps
end
end
end
I've run into this before when a migration didn't run as expected. But you should also check your schema.rb file to make sure that the votes table has the columns that the migration adds.
Here are my two models
class Comment < ActiveRecord::Base
belongs_to :phone
end
class Phone < ActiveRecord::Base
has_many :comments, :dependent => :destroy
end
Here is the schema for the tables
ActiveRecord::Schema.define(version: 20131119231249) do
create_table "comments", force: true do |t|
t.string "username"
t.string "ipaddy"
t.text "pcomments"
t.string "company"
t.string "calltype"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "pnumber"
t.string "source"
end
create_table "phones", force: true do |t|
t.integer "pnumber"
t.text "mrcomment"
t.integer "ccount"
t.datetime "created_at"
t.datetime "updated_at"
end
end
Here is the raw SQL that works
SELECT phones.ccount ,
comments.*
FROM phones
INNER JOIN comments
ON phones.pnumber = comments.pnumber;
When I run the following in my controller
#phones = Phone.select("phones.ccount, comments.*").joins(:comments).where(:comments => {comments.pnumber => phones.pnumber})
I get the following error
undefined local variable or method `comments' for #<FrontPageController:0x00000003c56c70>
Any help on what the active record statement should like would be greatly appreciated
It seems like you're using the select() erroneously. Have you read the docs: http://apidock.com/rails/ActiveRecord/QueryMethods/select ?
from docs: "Second: Modifies the SELECT statement for the query so that only certain fields are retrieved:"
The query's syntax should more look like (using a standard example):
l = Location.where(["id = ?", id]).select("name, website, city").first.
I am trying to do a query in in Rails with ActiveRecord that specifies some condition on a joined table. And i can't seem to get it to work, even though i follow the examples from here:
http://guides.rubyonrails.org/active_record_querying.html#specifying-conditions-on-the-joined-tables
From the guides:
Client.joins(:orders).where(:orders => {:created_at => time_range})
My database schema looks like this, with tables scores, submissions and tasks:
create_table "scores", :force => true do |t|
t.integer "value"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "scores", ["user_id"], :name => "index_scores_on_user_id"
create_table "submissions", :force => true do |t|
t.integer "user_id"
t.integer "task_id"
t.integer "score_id"
t.datetime "completed_at"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "submissions", ["score_id"], :name => "index_submissions_on_score_id"
add_index "submissions", ["task_id"], :name => "index_submissions_on_task_id"
add_index "submissions", ["user_id"], :name => "index_submissions_on_user_id"
create_table "tasks", :force => true do |t|
t.integer "episode_id"
t.integer "score"
t.string "key"
t.datetime "created_at"
t.datetime "updated_at"
end
So i want to do a query where I can find all "scores" that have a relation to a spesific task. Submission belongs to tasks and scores.
My query now looks like this:
Score.joins(:submission).where(:submission => {:task_id => 1})
This generates the following syntax:
SELECT "scores".* FROM "scores" INNER JOIN "submissions" ON "submissions"."score_id" = "scores"."id" WHERE "submission"."task_id" = 1
Which generates the following error:
SQLite3::SQLException: no such column: submission.task_id
But there is a column submission.task_id, which you can see in the db schema. And i can do this successfully:
SELECT "submissions".* FROM "submissions" WHERE "submissions"."task_id" = 1
The name in the clause should be plural to reference the table name:
Score.joins(:submission).where(:submissions => {:task_id => 1})
I find this to be easier.
Score.joins(:submission).merge(Submission.where(task_id: 1))
The clause name should be plural to reference the table name.
Score.joins(:submission).where(submissions: { task_id: 1 })
If score has many submissions, the joins symbol should also be plural to reference the relation between Score and Submission.
Score.joins(:submissions).where(submissions: { task_id: 1 })
A caveat: if you're using non-standard table names the above will fail like so:
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: missing FROM-clause entry for table "submissions"
To fix this, put (joined-model-class).table_name as a key in the where hash:
Score.joins(:submission).where(
Submission.table_name => {task_id: 1}
)
I'm a little stumped as to get the order of records I want with a find operation.
Let's say you had three models:
1. Websites
2. Links
3. Votes
A website has many links and a link has many votes. Each vote has a certain amount of points that a user can attribute to that vote. I'm trying to get a website index page where websites are listed in order of the sum of the points they've received for all the links for that website.
Here's a simplified version of the schema
create_table "votes", :force => true do |t|
t.integer "link_id"
t.integer "points"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
end
create_table "links", :force => true do |t|
t.string "name"
t.string "link"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
t.integer "votes_count", :default => 0
t.integer "website_id"
end
create_table "websites", :force => true do |t|
t.string "domain"
t.boolean "verified", :default => false
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
I'm trying to think about the right active record query to use here. Any help would be appreciated.
To think that I spent a day pulling my hair out when I came up with a solution just an hour after I posted this question.
In the website model I put that the website has_many :points, through => :links
Then the query:
array = Website.find(:all)
array.sort_by {|w| w.donations.sum('amount')}.reverse
This seems to work.