belongs_to with :class_name option fails - ruby-on-rails

I have no idea what went wrong but I can't get belongs_to work with :class_name option. Could somebody enlighten me. Thanks a lot!
Here is a snip from my code.
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.text :name
end
end
def self.down
drop_table :users
end
end
#####################################################
class CreateBooks < ActiveRecord::Migration
def self.up
create_table :books do |t|
t.text :title
t.integer :author_id, :null => false
end
end
def self.down
drop_table :books
end
end
#####################################################
class User < ActiveRecord::Base
has_many: books
end
#####################################################
class Book < ActiveRecord::Base
belongs_to :author, :class_name => 'User', :validate => true
end
#####################################################
class BooksController < ApplicationController
def create
user = User.new({:name => 'John Woo'})
user.save
#failed_book = Book.new({:title => 'Failed!', :author => #user})
#failed_book.save # missing author_id
#success_book = Book.new({:title => 'Nice day', :author_id => #user.id})
#success_book.save # no error!
end
end
environment:
ruby 1.9.1-p387
Rails 2.3.5

class User < ActiveRecord::Base
has_many :books, :foreign_key => 'author_id'
end
class Book < ActiveRecord::Base
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id', :validate => true
end
The best thing to do is to change your migration and change author_id to user_id. Then you can remove the :foreign_key option.

It should be
belongs_to :user, :foreign_key => 'author_id'
if your foreign key is author id. Since you actually have User class, your Book must belong_to :user.

I do in this way:
Migration -
class AddAuthorToPosts < ActiveRecord::Migration
def change
add_reference :posts, :author, index: true
add_foreign_key :posts, :users, column: :author_id
end
end
class Post
belongs_to :author, class_name: "User"

migration
t.belongs_to :author, foreign_key: { to_table: :users }
working on rails 5

Related

What kind of relationship should be used for tables Transaction and User - Ruby on Rails?

I am new learner. I just started learning more about Backend with Ruby on Rails.
I have the following tables - User and User_Transaction.
So basically I want to have a transaction which holds information about the sender and the receiver. This personally sounds to me more like a has_and_belongs_to_many relation. However, I am really confused in how to approach this and how should I include the 2 foreign keys.
I am curious to learn more about this and I will be really happy if someone helps me :).
Migrations
User
class CreateUsers < ActiveRecord::Migration[6.0]
def change
create_table :users do |t|
t.integer :username
t.integer :password
t.timestamps
end
end
end
Transaction
class CreateTransactions < ActiveRecord::Migration[6.0]
def change
create_table :transactions do |t|
t.string :sender
t.string:receiver
t.decimal :amount
t.timestamps
end
end
end
Models
Transaction
class ::Transaction < ApplicationRecord
#We have two users per transaction 'Sender' and 'Receiver'
has_and_belongs_to_many :users
# belongs_to :sender, :class_name => 'User'
# belongs_to :receiver, :class_name => 'User'
end
User
class User < ApplicationRecord
# has_many :accounts
# has_many :transactions
has_and_belongs_to_many :transactions
end
how about this:
migrations
class CreateUsers < ActiveRecord::Migration[6.0]
def change
create_table :users do |t|
t.string :username
t.string :password
t.timestamps
end
end
end
class CreateTransactions < ActiveRecord::Migration[6.0]
def change
create_table :transactions do |t|
t.references :sender, index: true, null: false, foreign_key: {to_table: :users}
t.references :receiver, index: true, null: false, foreign_key: {to_table: :users}
t.decimal :amount
t.timestamps
end
end
end
models
class User < ApplicationRecord
has_many :send_transactions, class_name: "Transaction", foreign_key: :sender, inverse_of: :sender
has_many :receive_transactions, class_name: "Transaction", foreign_key: :receiver, inverse_of: :receiver
end
class Transaction < ApplicationRecord
belongs_to :sender, class_name: "User", inverse_of: :send_transactions
belongs_to :receiver, class_name: "User", inverse_of: :receive_transactions
end

migration with two belongs_to for the same table

I have the next two models
class Currency < ActiveRecord::Base
# something ...
end
class CurrencyRate < ActiveRecord::Base
attr_accessible :rate
belongs_to :currency_to_convert, :class_name => 'Currency'
belongs_to :currency_converted, :class_name => 'Currency'
end
how should I create the migration for the CurrencyRate model, only with one field for the foreign key association or two fields?
I have been thinking in something like
class CreateCurrencyRates < ActiveRecord::Migration
def change
create_table :currency_rates do |t|
t.integer :currency_id
t.timestamps
end
end
end
but I'm not sure if works for a model with two belongs_to associations.
class CurrencyRate < ActiveRecord::Base
attr_accessible :rate
belongs_to :currency_to_convert, :class_name => 'Currency', :foreign_key => 'currency_convert_id'
belongs_to :currency_converted, :class_name => 'Currency', :foreign_key => 'currency_converted_id'
end
class CreateCurrencyRates < ActiveRecord::Migration
def change
create_table :currency_rates do |t|
t.integer :currency_converted_id
t.integer :currency_convert_id
t.timestamps
end
end
end

Rename foreign_key to override in Rails Convention

I have a problem in association between two classes, so i have a class table here named Post
Class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :post_type , null: false
t.text :content , null: false
t.integer :person_id
end
add_index :posts, :person_id
add_index :posts, :group_id
end
end
and the other one is called Action
class CreateActions < ActiveRecord::Migration
def change
create_table :actions do |t|
t.string :target_type, null:false
t.integer :target_id
t.integer :upvote_count
t.timestamps
end
add_index :actions,:target_id
end
end
so the problem is i want to associate the target_is as the foreign key to the Post class so i did this
class Post < ActiveRecord::Base
has_one :action
end
class Action < ActiveRecord::Base
belongs_to :post , :class_name => 'Target', :foreign_key => 'target_id'
end
but is doesn't work, which when i assign Action object to action method in Post object this error is appeared
Mysql2::Error: Unknown column 'actions.post_id' in 'where clause': SELECT `actions`.* FROM `actions` WHERE `actions`.`post_id` = 6 LIMIT 1
so any help?
You need to set the foreign key on both sides of the association:
class Post < ActiveRecord::Base
has_one :action, :foreign_key => 'target_id'
end
class Action < ActiveRecord::Base
belongs_to :post , :class_name => 'Target', :foreign_key => 'target_id'
end
http://guides.rubyonrails.org/association_basics.html#has_one-association-reference
http://guides.rubyonrails.org/association_basics.html#belongs_to-association-reference
I suppose you are trying to apply polymorphic association. Try this out.
class Post < ActiveRecord::Base
has_one :action, :as => :target
end
class Action < ActiveRecord::Base
belongs_to :target, :polymorphic => true
end

Eager Load Polymorphic has_many :through Associations in ActiveRecord?

How do you eager load polymorphic has_many :through associations in Rails/ActiveRecord?
Here's the base setup:
class Post < ActiveRecord::Base
has_many :categorizations, :as => :categorizable
has_many :categories, :through => :categorizations
end
class Category < ActiveRecord::Base
has_many :categorizations, :as => :category
has_many :categorizables, :through => :categorizations
end
class Categorization < ActiveRecord::Base
belongs_to :category, :polymorphic => true
belongs_to :categorizable, :polymorphic => true
end
Assuming that we want to solve this eager loading problem for Rails 2.3.x and double polymorphic associations on the join model, how do you eager load the :through association on something like this:
posts = Post.all(:include => {:categories => :categorizations})
post.categories # no SQL call because they were eager loaded
That's not working, any ideas?
This is easier to accomplish with has_many :through. Do you have a specific reason for wanting to use polymorphic associations?
With has_many :through you can use this ActiveRecord query
posts = Post.all(:include => [:categorizations, :categories])
posts[0].categories # no additional sql query
posts[0].categorizations # no additional sql query
Model definitions
class Post < ActiveRecord::Base
has_many :categorizations
has_many :categories, :through => :categorizations
end
class Category < ActiveRecord::Base
has_many :categorizations
has_many :posts, :through => :categorizations
end
class Categorization < ActiveRecord::Base
belongs_to :post
belongs_to :category
end
Using these migrations
class CreatePosts < ActiveRecord::Migration
def self.up
create_table :posts do |t|
t.string :title
t.timestamps
end
end
def self.down
drop_table :posts
end
end
class CreateCategories < ActiveRecord::Migration
def self.up
create_table :categories do |t|
t.string :name
t.timestamps
end
end
def self.down
drop_table :categories
end
end
class CreateCategorizations < ActiveRecord::Migration
def self.up
create_table :categorizations do |t|
t.integer :post_id
t.integer :category_id
t.timestamps
end
end
def self.down
drop_table :categorizations
end
end

AssociationTypeMismatch problem when saving data

in a previous question i was stumped.. but stack overflow provided the solution
my two models
class Team < ActiveRecord::Base
has_many :fixtures, :finder_sql => 'SELECT * FROM fixtures where (home_team = #{id} or away_team = #{id})'
has_many :home_fixtures, :class_name => "Fixtures", :foreign_key => :home_team
has_many :away_fixtures, :class_name => "Fixtures", :foreign_key => :away_team
has_many :teamalias
end
class Fixture < ActiveRecord::Base
belongs_to :league
belongs_to :selection
has_many :selection
named_scope :for_team_id, lambda{|team_id| {:conditions => ['(home_team = ? or away_team = ?)', team_id, team_id]} }
belongs_to :home_team, :class_name => "Team", :foreign_key => :home_team
belongs_to :away_team, :class_name => "Team", :foreign_key => :away_team
def fix_list
[home_team.title, "Draw", away_team.title]
end
end
taken from
Multi level associations in rails
but I'm stumped again- i'm trying to save a fixture based on the last solution in the first answer above and I am getting a typemismatch of.
Team(#38391330) expected, got String(#1242130)
no idea what to do here please help.
edit- db migrations
Here is the migrations
class CreateFixtures < ActiveRecord::Migration
def self.up
create_table :fixtures do |t|
t.integer :home_team
t.integer :away_team
t.datetime :when
t.integer :league_id
t.timestamps
end
end
def self.down
drop_table :fixtures
end
end
class CreateTeams < ActiveRecord::Migration
def self.up
create_table :teams do |t|
t.string :title
t.timestamps
end
end
def self.down
drop_table :teams
end
end
class AddResultToFixture < ActiveRecord::Migration
def self.up
add_column :fixtures, :result, :integer
end
def self.down
remove_column :fixtures, :result
end
end
your form probably has fixture[home_team] which is a select which passes the team.id
so when you do
#fixture = Fixture.new(params[:fixture])
#fixture.save
you are calling home_team= team.id team.id is a string but home_team should be a Team object

Resources