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
Related
I have three tables in my Rails 4 app -- one for Game, Category, and Topic. Both Category and Topic have a column for :name, while Game includes information like starts_at for when a game begins.
In my PagesController, I can show data from both Game and Topic by using find_by with the params value:
topic = Topic.find_by_name(params[:topic])
#games = Game.for_topic(topic).upcoming.order(:starts_at)
This works fine.
What's weird is that when I use the same reasoning but with Category instead of Topic, like so:
category = Category.find_by_name(params[:category])
#games = Game.for_category(category).upcoming.order(:starts_at)
I receive an error message:
undefined method `for_category'
This is confusing to me since I am definitely defining category and the using it in my for_ expression. Am I making an error in my thinking?
Additional
CreateCategories Migration
class CreateCategories < ActiveRecord::Migration
def change
create_table :categories do |t|
t.belongs_to :topic, index: true
t.string :name, :null => false
t.timestamps
end
end
end
CreateTopics Migration
class CreateTopics < ActiveRecord::Migration
def change
create_table :topics do |t|
t.string :name, :null => false
t.timestamps
end
end
end
I think you setup the named scope for_topic in the Game model. But is missing the for_category, which is why it is failing.
Try setting the named scope for_category in Game model.
I have a simple Rails application I'm using to try and learn Rails.
It has a database table I create like this using ActiveRecord:
class CreateMovies < ActiveRecord::Migration
def up
create_table :movies do |t|
t.string :title
t.string :rating
t.text :description
t.datetime :release_date
t.timestamps
end
end
def down
drop_table :movies
end
end
Here is my corresponding model class:
class Movie < ActiveRecord::Base
def self.all_ratings
%w(G PG PG-13 NC-17 R)
end
def name_with_rating()
return "#{#title} (#{#rating})"
end
end
When I call name_with_rating on an instance of Movie, all it returns is " ()" for any Movie. What is the correct syntax or method to call to get at the fields of the Movie instance from within an instance method of Movie?
Please note that the database has been properly populated with movie rows, etc. I've done rake db:create, rake db:migrate etc.
Active record attributes aren't implemented as instance variables. Try
class Movie < ActiveRecord::Base
def name_with_rating()
return "#{title} (#{rating})"
end
end
class Movie < ActiveRecord::Base
def name_with_rating
"#{title} (#{rating})"
end
end
then in the console Movie.first.name_with_rating should work.
I'm a beginner in Rails, and I'm having trouble inserting rows into the database using Rails's migration.
class Actions < ActiveRecord::Migration
def up
create_table :actions do |t|
t.integer :channel_id
t.string :name
t.text :description
t.integer :weight
t.timestamps
end
add_index :actions, :channel_id
Actions.create :name => 'name', :description => '', :weight => 1, :channel_id => 1
end
Running this code results in:
== Actions: migrating ========================================================
-- create_table(:actions)
-> 0.0076s
-- add_index(:actions, :channel_id)
-> 0.0036s
-- create({:name=>"name", :description=>"", :weight=>1, :channel_id=>1})
rake aborted!
An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: unrecognized token: "{": {:name=>"name", :description=>"", :weight=>1, :channel_id=>1}
The Action model:
class Actions < ActiveRecord::Base
belongs_to :channels
attr_accessible :name, :description, :weight, :channel_id
end
I don't know where the curly brackets come from and why they cause an exception. Who can help me solving this problem?
Uh oh, it seems that your migration class name is the same as the name of the model you're trying to access (Actions). Because of this, instead of the model class, the create method will be called on the migration class, which probably tries to create a table using your hash, or something. That's why you're getting that error message.
Rename your migration class (and also its file for the sake of consistency) and it should run fine:
class CreateActions < ActiveRecord::Migration
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.
I created a simple example as a sanity check and still can not seem to destroy an item on either side of a has_and_belongs_to_many relationship in rails.
Whenever I try to delete an object from either table, I get the dreaded NameError / "uninitialized constant" error message.
To demonstrate, I created a sample rails app with a Boy class and Dog class. I used the basic scaffold for each and created a linking table called boys_dogs. I then added a simple before_save routine to create a new 'dog' any time a boy was created and establish a relationship, just to get things setup easily.
dog.rb
class Dog < ActiveRecord::Base
has_and_belongs_to_many :Boys
end
boy.rb
class Boy < ActiveRecord::Base
has_and_belongs_to_many :Dogs
def before_save
self.Dogs.build( :name => "Rover" )
end
end
schema.rb
ActiveRecord::Schema.define(:version => 20100118034401) do
create_table "boys", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "boys_dogs", :id => false, :force => true do |t|
t.integer "boy_id"
t.integer "dog_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "dogs", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
end
I've seen lots of posts here and elsewhere about similar problems, but the solutions are normally using belongs_to and the plural/singular class names being confused. I don't think that is the case here, but I tried switching the habtm statement to use the singular name just to see if it helped (with no luck). I seem to be missing something simple here.
The actual error message is:
NameError in BoysController#destroy
uninitialized constant Boy::Dogs
The trace looks like:
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:105:in const_missing'
(eval):3:indestroy_without_callbacks'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/callbacks.rb:337:in destroy_without_transactions'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/transactions.rb:229:insend'
...
Thanks.
I don't see your destroy callback, but I do see a couple of problems. First, your associations need to be lowercase. So dog.rb should be:
class Dog < ActiveRecord::Base
has_and_belongs_to_many :boys
end
and boy.rb should be:
class Boy < ActiveRecord::Base
has_and_belongs_to_many :dogs
def before_save
self.dogs.build( :name => "Rover" )
end
end
Second, I believe you want to use self.dogs.create instead of self.dogs.build above, since build won't actually save the new dog object.
The accepted answer here solved my problem, only to create another one.
Here are my model objects:
class Complex < ActiveRecord::Base
set_table_name "Complexes"
set_primary_key "ComplexID"
has_and_belongs_to_many :amenities
end
class Amenity < ActiveRecord::Base
set_table_name "Amenities"
set_primary_key "AmenityID"
end
Rails uses the name of the association as the table name when creating the select query. My application runs on Unix against a legacy MySQL database and my table names are case-sensitive and don't conform to Rails conventions. Whenever my app actually tried to load the association, I would get an exception that MySQL couldn't find table amenities:
SELECT * FROM `amenities`
INNER JOIN `ComplexAmenities` ON `amenities`.AmenityID = `ComplexAmenities`.AmenityID
WHERE (`ComplexAmenities`.ComplexID = 147 )
I searched and searched and could not find a way to tell Rails to use the correct case for the table name. Out of desperation, I tried passing a :table_name option to habtm and it worked. My new Complex model looks like this:
class Complex < ActiveRecord::Base
set_table_name "Complexes"
set_primary_key "ComplexID"
has_and_belongs_to_many :amenities, :table_name => 'Amenities'
end
This works under Rails 2.3.5.
This option is not mentioned in the Ruby on Rails docs.