rails foreign key problem - ruby-on-rails

I am a newbie in the Rails framework. I've created tables:
DealerGroups Dealer
------------ ------------
Id:integer(primary key) Id:integer(primary key)
name:string dealer_group_id:integer(foreign key)
But when I try to set Dealer.dealer_group_id = value (this value exists in the DealerGroups table) I get an "UninitializedConstant Dealer::DealerGroup" exception.
In models I have :
class Dealer < ActiveRecord::Base
belongs_to :dealer_buying_group, :foreign_key => "dealer_buying_group"
end
class DealersGroup < ActiveRecord::Base
has_many :dealer
end
If I delete the has_many and belongs_to relations, it all works fine.
Why won't it work with the relations?

Be careful with the "s" (why is your "Dealer" table is not "Dealers"?)
You do not need to manually set a foreign key in Rails, all you need to define the Model_ID field to it as you generate your scaffold/model/controller, then belongs_to and has_many in the model will do the relation for you
Database:
DealerGroups Dealers
------------ ------------
Id:integer(primary key) Id:integer(primary key)
name:string dealergroup_id:integer
Models :
class Dealer < ActiveRecord::Base
belongs_to :dealergroup
end
class DealersGroup < ActiveRecord::Base
has_many :dealers
end
To access dealdergroup's name from dealers, just use
controller:
#dealer = Dealer.find_by_id(myInt)
view:
<%= #dealer.dealergroup.name %>

You have class DealersGroup whereas you are looking for dealer_group_id.

Related

Create Rails scope comparing fields on two tables

I have a number of associated tables in an application
class Listing < ActiveRecord::Base
belongs_to :house
belongs_to :multiple_listing_service
end
class House < ActiveRecord::Base
has_one :zip_code
has_one :primary_mls, through: :zip_code
end
I wanted to create a scope that produces all the Listings that are related to the Primary MLS for the associated House. Put another way, the scope should produce all the Listings where the multiple_listing_service_id = primary_mls.id for the associated house.
I've tried dozens of nested joins scopes, and none seem to work. At best they just return all the Listings, and normally they fail out.
Any ideas?
If I understand correctly, I'm not sure a pure scope would be the way to go. Assuming you have:
class MultipleListingService < ActiveRecord::Base
has_many :listings
has_many :zip_codes
end
I would go for something like:
class House < ActiveRecord::Base
...
def associated_listings
primary_mls.listings
end
end
Update 1
If your goal is to just get the primary listing then I would add an is_primary field to the Listing. This would be the most efficient. The alternative is a 3 table join which can work but is hard to optimize well:
class Listing < ActiveRecord::Base
...
scope :primary, -> { joins(:houses => [:zip_codes])
.where('zip_codes.multiple_listing_service_id = listings.multiple_listing_service_id') }

SIT in rails not working for audited-activerecord

I am not able to retrieve auditable_type for the child table record associated audits as it always gives parent table class name.
I have:
class Patient < ActiveRecord::Base
has_many :diseases
has_associated_audits
end
class Disease < MedicalHistory
belongs_to :patient
audited associated_with :patient
end
class MedicalHistory < ActiveRecord::Base
end
when I make Patient.last.associated_audits.last.auditable_type give MedicalHistory instead of Disease.
Please let me know ASAP.
Yes it has been an issue in this gem.
But you can retrieve the audited record first and then identify its class name like :
Patient.last.associated_audits.last.auditable.class.name
Actually, in Single table inheritance (STI) each record will have a unique id so you can identify the record using the record id from the parent class as MedicalHistory.find(child_id)

How to write active record query to details by using and

i have two tables
1)Properties :fields are id, name, propert_type,category_id
2)Admins : fields id, name,mobile,category_id
i want to write an active record to list all properties , where category_id in properties table and category_id in Admins table are equal, according to current_user_id
i am listing this property list by logging as admin.
model relation
class Category < ActiveRecord::Base
has_many :admins,dependent: :destroy
has_many :properties,dependent: :destroy
end
class Admin < ActiveRecord::Base
belongs_to :category
has_many :properties
end
class Property < ActiveRecord::Base
belongs_to :admin
belongs_to :category
end
i wrote active record like this , but i got error,
can anyone please suggest me a solution for this
#properties= Property.where('properties.category_id=?','admins.category_id=?').and('admins.id=?',current_user.specific.id)
With your assosciation,You can use a sub query for getting your result in one line
#properties = Property.where(category_id: Admin.select("category_id").where(id: current_user.id))
As per my understanding current_user is an Admin. So You can search by the category_id of current_user. If I'm right, try this
#properties = Property.where(category_id: current_user.category_id)

Rails association in concerns

I am using concerns for my rails application. I've different kind of users so I have made a loggable.rb concern.
In my concern I have
included do
has_one :auth_info
end
because every of my user that will include the concern will have an association with auth_info table.
The problem is, what foreign keys I need to put in my auth_info table?
E.G
I've 3 kind of users:
customer
seller
visitor
If I had only customer, in my table scheme I would have put the field
id_customer
but in my case?
You can solve this with polymorphic associations (and drop the concern):
class AuthInfo < ActiveRecord::Base
belongs_to :loggable, polymorphic: true
end
class Customer < ActiveRecord::Base
has_one :auth_info, as: :loggable
end
class Seller < ActiveRecord::Base
has_one :auth_info, as: :loggable
end
class Visitor < ActiveRecord::Base
has_one :auth_info, as: :loggable
end
Now you can retrieve:
customer.auth_info # The related AuthInfo object
AuthInfo.first.loggable # Returns a Customer, Seller or Visitor
You can use rails g model AuthInfo loggable:references{polymorphic} to create the model, or you can create the migration for the two columns by hand. See the documentation for more details.
Since user has roles 'customer', 'seller', 'visitor'.
Add a column called role to Users table.
Add a column called user_id to auth_infos table.
class AuthInfo < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_one :auth_info
end
you can do
user = User.first
user.auth_info
Now you a additional logic to your concerns.

Rails has_one not saving foreign key

I have the following tables
keyword
keyword_id - PK
description
status_id - FK
keyword_status
status_id - PK
description
Trying to model them in AR and when attempting to save in my test it's not saving the status ID in keyword. They are mapped as such:
class Keyword < ActiveRecord::Base
self.table_name = :keyword
self.primary_key = :KEYWORD_ID
attr_writer :description
attr_writer :keyword_status
has_one :keyword_status, foreign_key: :STATUS_ID
end
class KeywordStatus < ActiveRecord::Base
self.table_name = :keyword_status
self.primary_key = :STATUS_ID
end
and the code where it breaks (keyword status is populated by a fixture)
keyword = Keyword.new
keyword.description = "keyword#{n}"
keyword.keyword_status = KeywordStatus.first
keyword.save
When keyword.save is called i get cannot insert NULL into 'STATUS_ID' on table Keyword
NOTE: I cannot change any of the DDL
As dstarh said, the foreign key association is backwards. In your models you should only need:
class Keyword < ActiveRecord::Base
has_one :keyword_status
end
class KeywordStatus < ActiveRecord::Base
belongs_to :keyword, :foreign_key => "status_id"
end
For the association to work. Also, setting the KeywordStatus object up with a fixture before creating the associated object is a bit odd but will work if that is the behavior you need. Also, why not just use the foreign key keyword_id and let rails handle it for you?
Update if you want to use keyword_id instead of status_id as the foreign key:
the tables will be as such:
keyword
id - PK
description
keyword_status
id - PK
keyword_id - FK
description
And your models:
class Keyword < ActiveRecord::Base
has_one :keyword_status
end
class KeywordStatus < ActiveRecord::Base
belongs_to :keyword
end
Hope this helps!
Update 2: Given the tables cannot change the association has to be a bit backwards. I would recommend:
class Keyword < ActiveRecord::Base
belongs_to :keyword_status
end
class KeywordStatus < ActiveRecord::Base
has_many :keywords, :foreign_key => "status_id"
end
I used a has many as the association since from what has been said it looks like a keyword can share a status that another keyword has. This also means that you will have to do something like:
KeywordStatus.first.keywords = KeywordStatus.first.keywords.push(keyword)
KeywordStatus.save
instead of:
keyword.keyword_status = KeywordStatus.first
Which operates in the opposite direction than you want. As you can see this can get pretty confusing so if at all possible i would suggest writing a migration to change your tables (this can be done for tables that have existing data if that is the problem). Again I hope this helps!
You got the direction wrong. It should be keyword belongs_to status. The general rule is that the model that has the foreign key column belongs to the other model.

Resources