I've been trying to solve this problem for a couple of hours but I can't seem to understand what's going on.
I'm using Rails 3 beta, and want to seed some data to the database. However, when I try to seed some values through db:seed, I get this error:
rake aborted!
Attribute(#81402440) expected, got Array(#69024170)
The seeds.rb is:
DataType.delete_all
DataType.create(
:name => 'String'
)
And I got these classes:
class DataType < ActiveRecord::Base
has_many :attributes
end
class Attribute < ActiveRecord::Base
belongs_to :data_types
end
Just to clarify, the intention is having Attribute objects have one data type (such as String, Number, etc.).
While the migration definition for DataType is merely:
class CreateDataTypes < ActiveRecord::Migration
def self.up
create_table :data_types do |t|
t.string :name
t.timestamps
end
end
def self.down
drop_table :data_types
end
end
Can anyone tell me what I'm doing wrong?
"Attribute" may be conflicting with something. Try renaming your Attribute model.
Related
I am pretty new to rails so this may be a dumb question, but I have spent hours debugging this seemingly simple error and gotten nowhere. In my database, I want each row to to store an array of numbers (in a variable called contributions). I read that the best way to do that was by adding the following code:
class Goal < ActiveRecord::Base
#...
serialize :contributions, Array
#...
end
The attribute is also in goal.rb
ActiveRecord::Schema.define(version: 20150711171452) do
create_table "goals", force: :cascade do |t|
#...
t.decimal "contributions"
#...
end
end
I added it via this migration:
class AddContributorsToGoals < ActiveRecord::Migration
def change
add_column :goals, :contributors, :string
add_column :goals, :contributions, :decimal
end
end
The only problem is that whenever I try to access this attribute, I always get errors stating that it is of type BigDecimal. Rails thinks that this is a single number, but I want it to be a list of numbers. Any ideas as to what I could be doing wrong?
One example of a problem I get is that when this executes:
#goal.contributions << #goal.lastUpdateAmount
but I get this error
undefined method `<<' for #<BigDecimal:7f95e082ab18,'-0.0',9(9)>
I followed identical steps with an array of strings and that was serialized properly. I just don't know what's going on with this one.
Please change data type decimal to text
class AddContributorsToGoals < ActiveRecord::Migration
def change
add_column :goals, :contributions, :text
end
end
I am trying to create a task management prototype. I created two models - Category and Task, while tasks belong to category and a category can contain many tasks.
class Category < ActiveRecord::Base
has_many :tasks
end
And
class Task < ActiveRecord::Base
belongs_to :category
end
Then in migration file
class CreateTasks < ActiveRecord::Migration
def change
create_table :tasks do |t|
t.string :name
t.string :note
t.references :category
t.timestamps null: false
end
end
end
and
class CreateCategories < ActiveRecord::Migration
def change
create_table :categories do |t|
t.string :name
t.string :description
t.timestamps null: false
end
end
end
I tried to seed some data to start working with, here's the seed file
c1 = Category.create(name: 'Category1')
Task.create(name: 'TASK1', category_id: c1.id)
However it gives me the error:
rake db:seed
rake aborted!
ActiveRecord::UnknownAttributeError: unknown attribute 'category_id' for Task.
I have tried the following as well
Task.create(name: 'TASK1', category: c1)
Task.create(name: 'TASK1', category: c1.id)
And I got the error
rake db:seed
rake aborted!
ActiveRecord::AssociationTypeMismatch: Category(#70174570341620) expected, got Fixnum(#70174565126780)
However in the browser, #category.id does load and display (as a two digit number 33).
Think I might be missing something obvious but can't figure out why I can't create the task associated with the specific category c1 in from the seeding the data
just need to pass the object:
c1 = Category.find_or_create_by(name: 'Category1')
I recommend to use find_or_create_by for not create twice the same data
Task.find_or_create_by(name: 'TASK1', category: c1)
if not work try create the same data in the console
I hope help you
I've been racking my head around a rails issue for a while and wanted to verify my findings. I was trying to get the Has_and_belongs_to_many relationship working, but couldn't connect my two classes, auctionItem and category. First of all, here was my migration file and the two classes before solving the issue:
Migration file:
class AuctionItemsCategories < ActiveRecord::Migration
def up
create_table 'auction_items_categories', :id=>false do |t|
t.reference :auctionItem_id
t.references :category_id
end
end
def down
drop_table 'auction_items_categories'
end
end
Category.rb
class Category < ActiveRecord::Base
has_and_belongs_to_many :auction_items
end
auction_item.rb
class AuctionItem < ActiveRecord::Base
has_and_belongs_to_many :categories
end
After creating an instance of AuctionItem, I tried
auction_item = AuctionItem.last
auction_item.categories
...and got the following error:
NoMethodError: undefined method `categories' for #<AuctionItem:0x0000010521b870>
After some research, I found adding the specific class to the has_and_belongs_to_many helped:
Category Model
has_and_belongs_to_many :auction_items , :class_name => 'AuctionItem'
auction_item Model
has_and_belongs_to_many :categories , :class_name => 'Category'
This solved that issue and I was able to access the categories table. I went on to try to append a category to the auction item:
auction_item.categories << category
I then got received the following error:
SELECT "auction_items".* FROM "auction_items" INNER JOIN "auction_items_categories" ON "auction_items"."id" = "auction_items_categories"."auction_item_id" WHERE "auction_items_categories"."category_id" = 2
SQLite3::SQLException: no such column: auction_items_categories.auction_item_id: SELECT "auction_items".* FROM "auction_items" INNER JOIN "auction_items_categories" ON "auction_items"."id" = "auction_items_categories"."auction_item_id" WHERE "auction_items_categories"."category_id" = 2
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: auction_items_categories.auction_item_id: SELECT "auction_items".* FROM "auction_items" INNER JOIN "auction_items_categories" ON "auction_items"."id" = "auction_items_categories"."auction_item_id" WHERE "auction_items_categories"."category_id" = 2
If you notice, the query is trying to get auction_item.id rather than AuctionItem.id. To get the connection to work, I had to change my migration file to the following:
class AuctionItemsCategories < ActiveRecord::Migration
def up
create_table 'auction_items_categories', :id=>false do |t|
t.integer :auction_item_id
t.integer :category_id
end
end
def down
drop_table 'auction_items_categories'
end
end
So long story short/TL DR version: For me, it seems that when naming your class with multiple words and using camel case, rails does not singularize your pluralized class name back to it's original state if it has an underscore. So for example, my class name was AuctionItem which became auction_items for the model. Rather than search for auctionitem.id, the sql call that was looked for was auction_item.id, which is the singularize version of auction_items. Why didn't it search for auctionitem.id? In the future, when I am making association tables with multi word classes, do I use the singular underscore id version of the model name?
Your original migration was incorrect. It should have been as follows:
class AuctionItemsCategories < ActiveRecord::Migration
def up
create_table 'auction_items_categories', :id => false do |t|
t.references :auction_item
t.references :category
end
end
def down
drop_table 'auction_items_categories'
end
end
You should specify the symbolized model name when using references.
I am trying to add two different attachment fields. The migration is failing wether i run it using bundler or without. (bundle exec rake db:migrate or just rake db:migrate).
== AddDiagramToQuestion: migrating ===========================================
-- change_table(:questions)
rake aborted!
An error has occurred, this and all later migrations canceled:
undefined method `has_attached_file' for #<ActiveRecord::ConnectionAdapters::Table:0x0000012b003b20>
/Users/kboon/Documents/workspace/quiztaker/db/migrate/20111213182927_add_diagram_to_question.rb:6:in `block in up'
/Users/kboon/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.1.1/lib/active_record/connection_adapters/abstract/schema_statements.rb:244:in `change_table'
The migration looks like this:
class AddDiagramToAnswer < ActiveRecord::Migration
def self.up
change_table :answers do |t|
t.has_attached_file :diagram
end
end
def self.down
drop_attached_file :answers, :diagram
end
end
The model also references methods added by paperclip and the app runs fine so its not that paperclip isn't installed at all. I've even tried added require 'paperclip' to the migration but that didn't help at all.
The migration that was created for me doesn't use the t.has_attached_file terminology anymore, it actually adds the columns explicitly. The migration would be created by running:
rails generate paperclip Answer diagram
Check out the example here.
This worked for me
def change
create_table :some_table do |t|
t.attachment :avatar
t.timestamps
end
end
Migration file should be look like
class AddDiagramToAnswer < ActiveRecord::Migration
def self.up
add_attachment :answers, :diagram
end
def self.down
remove_attachment :answers, :diagram
end
end
or
class AddDiagramToAnswer < ActiveRecord::Migration
def change
create_table :users do |t|
t.attachment :avatar
end
end
end
has_attached_file is used in model.rb(answer.rb in your app)
with rails 5
Let's say I'm starting out with this model:
class Location < ActiveRecord::Base
attr_accessible :company_name, :location_name
end
Now I want to refactor one of the values into an associated model.
class CreateCompanies < ActiveRecord::Migration
def self.up
create_table :companies do |t|
t.string :name, :null => false
t.timestamps
end
add_column :locations, :company_id, :integer, :null => false
end
def self.down
drop_table :companies
remove_column :locations, :company_id
end
end
class Location < ActiveRecord::Base
attr_accessible :location_name
belongs_to :company
end
class Company < ActiveRecord::Base
has_many :locations
end
This all works fine during development, since I'm doing everything a step at a time; but if I try deploying this to my staging environment, I run into trouble.
The problem is that since my code has already changed to reflect the migration, it causes the environment to crash when it attempts to run the migration.
Has anyone else dealt with this problem? Am I resigned to splitting my deployment up into multiple steps?
UPDATE It appears I am mistaken; when migrating a coworker's environment we ran into trouble, but staging updated without issue. Mea Culpa. I'll mark #noodl's reply as the answer to bury this, his post is good advice anyway.
I think the solution here is to not write migrations which have any external dependencies. Your migrations should not depend on the past or current state of your model in order to execute.
That doesn't mean that you can't use your model objects, just that you shouldn't use the versions found in whatever version of your code happens to be installed when you run a particular migration.
Instead consider redefining your model objects within your migration file. In most cases I find that an empty model class extending ActiveRecord::Base or a very stripped down version of the model class I was using at the time I wrote the migration allows me to write a reliable, future proof, migration without needing to convert ruby logic into SQL.
#20110111193815_stop_writing_fragile_migrations.rb
class StopWritingFragileMigrations < ActiveRecord::Migration
class ModelInNeedOfMigrating < ActiveRecord::Base
def matches_business_rule?
#logic copied from model when I created the migration
end
end
def self.up
add_column :model_in_need_of_migrating, :fancy_flag, :boolean, :default => false
#do some transform which would be difficult for me to do in SQL
ModelInNeedOfMigrating.all.each do |model|
model.update_attributes! :fancy_flag => true if model.created_at.cwday == 1 && model.matches_business_rule?
#...
end
end
def self.down
#undo that transformation as necessary
#...
end
end
What error are you getting when you run the migrations? You should be fine as long as your rake files and migrations don't use your models (and they shouldn't).
You'll also want to switch the order of your drop_table and remove_column lines in the self.down of your migration.