Multiple Foreign Keys in One Table - ruby-on-rails-3

I have two models called 'Event' & 'Currency'.
In the Event model the respective fields are id, prize_pool, title, name, currency_id, prize_pool_currency_id and in Currency model their fields are id, currency.
Event.rb
class Event < ActiveRecord::Base
attr_accessible :prize_pool,:title,:name,:currency_id,:prize_pool_currency_id
belongs_to :buy_currency, :class_name => 'Currency', :foreign_key => 'currency_id'
belongs_to :prize_pool_currency, :class_name => 'Currency', :foreign_key => 'prize_pool_currency_id'
end
Currency.rb
class Currency < ActiveRecord::Base
attr_accessible :currency
has_one :event
has_one :event_player
end
In the controller when we access it I'm given this error:
"Association named 'currency' was not found; perhaps you misspelled it?"
How to access or associate to one another so that all foreign key access easily?

You can access association using the name you gave for the association(not the class name). In your case, it would be buy_currency or prize_pool_currency
#poker_result = Event.includes(:buy_currency)

Related

When using has_many with custom foreign_key i get an undefined method error, in Rails 3

The first model:
class FaqGroup < ActiveRecord::Base
has_many :faqs, :foreign_key => 'group_id', :order => 'position'
acts_as_list
end
The second model:
class Faq < ActiveRecord::Base
belongs_to :faq_group, :foreign_key => 'group_id'
acts_as_list :scope => :faq_group
end
The controller:
def new_faq
#group = FaqGroup.find(params[:id])
#faq = #group.faqs.create(question: 'lorem', answer: 'ipsum')
end
When i load that in the browser I get the following error:
undefined method `faq_group_id' for #<Faq:0xb56fcde4>
So, basically when I try to create a new associated object, the foreign_key just gets ignored. If i give up the custom :foreign_key everything works great.
Another observation would be that if I do:
#group = FaqGroup.find(params[:id])
#faqs = #group.faqs
it WORKS ok, so it seems that it has problems using the foreign_key only when it creates new associated objects.
Thank you!
Check the belongs_to association with the foreign key option.
As mentioned there,
For foreign key in belongs_to-
"Specify the foreign key used for the association. By default this is guessed to be the name of the association with an “_id” suffix. So a class that defines a belongs_to :person association will use “person_id” as the default :foreign_key. Similarly, belongs_to :favorite_person, :class_name => "Person" will use a foreign key of “favorite_person_id”."
So in context with it, the error is because you defined:
class Faq < ActiveRecord::Base
belongs_to :faq_group, :foreign_key => 'group_id'
This association requires faq_group_id as the foreign key and not the group_id.
So is the error -
undefined method `faq_group_id' for #<Faq:0xb56fcde4>

rails has one through association

i have a user model with fields name and sex. And user can have an one-to-one association called "spouse" with another user, the association must be between a male user and a female user.
with the help of railscasts self-referential-association i create the basic association like this,
class User < ActiveRecord::Base
has_one :spouse_list
has_one :spouse, :through => :spouse_list
has_one :inverse_spouse_list, :class_name => "SpouseList", :foreign_key => "spouse_id"
has_one :inverse_spouse, :through => :inverse_spouse_list, :source => :user
end
class SpouseList < ActiveRecord::Base
belongs_to :spouse, :class_name => "User"
belongs_to :user
end
SpouseList has fields :spouse_id, :user_id,
above association can create many rows for single user and shows the first row if access spouse by #user.spouse_list.spouse.name
How can i restrict between a male user and a female user?
finally i made one-to-one self association for the below condition,
"User can have an one-to-one association called "spouse" with another user, the association must be between a male user and a female user"
added a field spouse_id to user model and created a self association with custom validation,
class User < ActiveRecord::Base
belongs_to :spouse, :class_name => 'User', :inverse_of => :base_user, :foreign_key => "spouse_id"
has_one :base_user, :class_name => 'User', :inverse_of => :spouse
validate :validate_spouse_gender
private
def validate_spouse_gender
errors.add(:spouse_id, 'could not be with same sex') if spouse && spouse.sex == sex
end
end
Now a male user A can only make association as spouse with another user B, if B is of gender female.
hope it helps someone.

Many to many relationship with metadata stored in the mapping table in activerecord

I have two tables with a many to many relationship, through a third table. In the third table is a piece of data I need to assign when I build the relationships between the two tables, how can I use ActiveRecords build method to assign that?
Here is code to show what I mean:
class Company < Contact
has_many :contact_companies
has_many :people, :through => :contact_companies
accepts_nested_attributes_for :people, :allow_destroy => true
accepts_nested_attributes_for :contact_companies
end
class Person < Contact
has_many :contact_companies
has_many :companies, :through => :contact_companies
accepts_nested_attributes_for :companies, :allow_destroy => true
accepts_nested_attributes_for :contact_companies
end
class ContactCompany < ActiveRecord::Base
belongs_to :person
belongs_to :company
end
ContactCompany contains a data member called "position". What I want to do is something like:
c = Person.new
c.companies.build(:name => Faker::Company.name, :position => positions.sample)
EDIT:
When I try the code above I get "unknown attribute: position".
The c.companies.build line is attempting to build a Company object which does not have the position attribute (the ContactCompany does) hence the error. It looks like you are trying to set attributes on two different models, so you'll have to make sure you are setting the appropriate attribute on the right model:
# you can chain these calls but I separated them for readability
cc = c.contact_companies.build(:position => positions.sample)
cc.build_company(:name => Faker::Company.name)

Rails has_many :through with custom foreign_key

I have the following set of models:
class Cardstock < ActiveRecord::Base
has_many :color_matches, :primary_key => :hex, :foreign_key => :hex
has_many :palette_colors, :through => :color_matches
end
class ColorMatch < ActiveRecord::Base
belongs_to :palette_color
has_many :cardstocks, :foreign_key => :hex, :primary_key => :hex
end
class PaletteColor < ActiveRecord::Base
has_many :color_matches
has_many :cardstocks, :through => :color_matches
end
Calling Cardstock.last.palette_colors yields the following error:
ActiveRecord::StatementInvalid: PGError: ERROR: operator does not exist: character varying = integer
LINE 1: ...".palette_color_id WHERE (("color_matches".hex = 66)) OR...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
: SELECT "palette_colors".* FROM "palette_colors" INNER JOIN "color_matches" ON "palette_colors".id = "color_matches".palette_color_id WHERE (("color_matches".hex = 66)) ORDER BY name ASC
This shows me that the query ActiveRecord generates is using the cardstock's id (66) where it should be using the cardstock's hex (bbbbaf). Somewhere, I need to specify to ActiveRecord to use the hex column to join between cardstocks and color_matches. Does ActiveRecord support this?
Your relationships are all out of whack here.
the relationships between Cardstock and ColorMatch should be a has_and_belongs_to_many relationship on both sides
anywhere you have a has_many relationship, you need a corresponding belongs_to relationship in the corresponding class
There's something wrong with the way your relationships are set up. I don't quite understand your specific use case here, so I'm not sure where the problem is. The way to think about this is probably as a many-to-many relationship. Figure out what the two sides of that many-to-many are, and what's the join model. I'm going to give an example assuming that ColorMatch is your join model -- it's what relates a PaletteColor to a Cardstock. In that case, you'll want your relationships to look something like this:
class Cardstock < ActiveRecord::Base
has_many :color_matches, :primary_key => :hex, :foreign_key => :hex
has_many :palette_colors, :through => :color_matches
end
class ColorMatch < ActiveRecord::Base
belongs_to :palette_color
belongs_to :cardstocks, :foreign_key => :hex, :primary_key => :hex
end
class PaletteColor < ActiveRecord::Base
has_many :color_matches
has_many :cardstocks, :through => :color_matches
end
In terms of your database, you should have a palette_color_id and a hex field on the color_matches table, and a hex field on the cardstocks table.

Two has_may association with Same model Rail 3

Hi im quite beginner in rails. i have a problem suggestion will be appreciated.
i have two model "user" and "asset"
an "asset" is created by a "user" and asset" can be assigned to a "user" schema is
Asset { id,name,creator_id,assigned_to_id,price,...}
User{ id,name,....}
now in Asset model class association are
class Asset < ActiveRecord::Base
{
#validation
belongs_to :creator ,:class_name=>'User'
belongs_to :assigned_to, :class_name=>'User' ,:foreign_key=>'assigned_to_id'
}
and User Model is
class User < ActiveRecord::Base
{
#any validation and other stuff
has_many :assets #did not specify either this association is for creator , or assigned_to user.how can is specify that??
}
now in Asset show view i can obtain creator name with
#asset.creator.name
but can't assigned_to name
#asset.assigned_to.name =>(error is )undefined method `first_name' for nil:NilClas
and
#asset.assigned_to_id.name=>(error is) undefined method `first_name' for 1:Fixnum
any suggestion how can i make double association with same model
ok solution was in my last comment.
Multiple relation with same model
class Asset < ActiveRecord::Base
belongs_to :creator ,:class_name=>'User'
belongs_to :assigned_to, :class_name=>'User'
end
user.rb
class User < ActiveRecord::Base
has_many :created_assets, :foreign_key => 'creator_id', :class_name => 'Asset'
has_many :assigned_assets , :foreign_key => 'assigned_to_id', :class_name => 'Asset'
end