Issue in alias model name in rails - ruby-on-rails

I have two models User and Dtype.
In users table I have two column named dtype_id and dtype_second which contains ID's of Dtype. Now I need to get both the columns values through association.
Using #user.dtype.name will give me the value of first column (dtype_id).
Now, I also need the value of second column i.e dtype_second.
For this I'm trying this:
In User Model:
belongs_to :dtype
In Dtype Model:
has_many :users
has_many :dtype_seconds, :foreign_key => 'dtype_second', :class_name => "User"
On view:
<%= #user.dtype_seconds.name %>
The issue is that I'm not getting any value or error.

First. Naming. You should rename dtype_second field to dtype_second_id
Next. Associations. You need appropriately describe both associations in both models
class User
belongs_to :dtype
belongs_to :dtype_second, :class_name => 'Dtype'
end
class Dtype
has_many :users
has_many :second_users, :class_name => 'User', :foreign_key => 'dtype_second_id'
end

Your are adding a has many to dtype, but you're trying to call the method on a user. So you have to define the dtype_second association on the user:
class User < ActiveRecord::Base
belongs_to :dtype
belongs_to :dtype_alternative, :foreign_key => 'dtype_second', :class_name => "Dtype"
...
end
<%= #user.dtype_alternative.name %>

Related

Association with the same model

I have two models 'Product' and 'Variant',product has many variants,now I have to set assocaiation of a new Model named as "Ingridient" with variant in such a way that Variant has many ingridients.but in ingridents I want to show that it again has_one product and variant.for example
class Variant
has_many :ingridients
belongs_to :product
end
class Ingridient
belongs_to :variant
belongs_to :product
end
now in my ingrident model I also want has_one variant and has_one product at the same time.how should I set my associations.I know multiple association with same table but dont know how to implement it in my app.Iam using mongoid as my database.
Edit : Actually in my flow User can create a Product with many variants and then each variant can have multiple ingridients.In that each ingrident i have select box for selecting products and variants form database .means ingridients will consist a product a variant ,quantity etc fields .To make it more clear Iam making a Recipe
.
I am not 100% clear on what you want to do.
But what it looks like is that you want to have a association with a different name.
class Variant
has_many :ingridients, :foreign_key => 'FieldName', :class_name => 'CassName'
belongs_to :product, :foreign_key => 'FieldName', :class_name => "CassName"
end
class Ingridient
belongs_to :variant, :foreign_key => 'FieldName', :class_name => "CassName"
belongs_to :product, :foreign_key => 'FieldName', :class_name => "CassName"
end
I hope that this helps

Has_many through with multiple relationships between the entities

I have these model definitions:
class Property < ActiveRecord::Base
belongs_to :user
has_many :users_favourites_properties, class_name: 'UsersFavouritesProperties', dependent: :destroy, :foreign_key => :property_id
has_many :favourites, :class_name => "User", through: :users_favourites_properties
end
class User < ActiveRecord::Base
has_many :properties
has_many :users_favourites_properties, class_name: 'UsersFavouritesProperties', dependent: :destroy, :foreign_key => :user_id
has_many :favourites, class_name: "Property", through: :users_favourites_properties
end
class UsersFavouritesProperties < ActiveRecord::Base
self.table_name = "favourites"
belongs_to :favourites, class_name: 'User', :foreign_key => :user_id, :primary_key => :id
belongs_to :favourites, class_name: 'Property', :foreign_key => :property_id, :primary_key => :id, counter_cache: :users_count
end
When I execute:
current_user.favourites << property
The UsersFavouritesProperties object created has the same user_id and property_id because the user_id is beign setted with the property_id.
Do you know what is happening?
You seem to misunderstand what the association name is for.
Each association method call (like has_many) adds certain methods to a model that allow for easy lookup for associated objects.
The name of association means (in scope of a model) "what is it for me". A symbol you specify first is an association name, and it is used (among other things) as a name of a method that you will use to access that association.
By defining an association named favourites once, you've defined the methods for UsersFavouritesProperties. The second time you define an association with the same name, some of the first one is redefined and crazy things can happen.
So, following that "what is it for me" principle, you can figure that a User associated with a certain UsersFavouritesProperty is UsersFavouritesProperty's user, and the resulting association, that you have:
belongs_to :favourites, class_name: 'User', :foreign_key => :user_id, :primary_key => :id
should be more like simple:
belongs_to :user
The rest is not even needed, as it follows the Rails' convention: class name and foreign key can be derived from association name in standard ways (capitalize for class name, add _id for foreign key), primary key is default.
I strongly recommend you read the Rails Style Guide and let ActiveRecord guess the most you can provide.
These lines
belongs_to :favourites, ...
belongs_to :favourites, ...
Should be
belongs_to :user, ...
belongs_to :property, ...
You can't use two keys for belongs_to

one to one relationship with columns that are not id

I have BudgetLine model. The model has budget_item_id column.
Second model is BudgetItem. it has an id and a column: full_name.
Now, I want to call: budget_line.item_name and get the name that is corresponding to the full_name in BudgetItem.
I tried (in BudgetLine):
has_one :item_name, :class_name => 'BudgetItem', :foreign_key => 'budget_item_id'
But it is not working.
Since your foreign key is in BudgetLine model, you should have belongs_to association in it:
belongs_to :item_name, class_name: 'BudgetItem', foreign_key: 'budget_item_id'
if you want to have method that returns only item_name, I'd advice renaming your association and adding separate method:
belongs_to :budget_item
def item_name
budget_item.try(:full_name)
end
instead of writing in BudgetLine
has_one :item_name, :class_name => 'BudgetItem', :foreign_key => 'budget_item_id'
You should write
belongs_to :item_name, :class_name => 'BudgetItem', :foreign_key => 'budget_item_id'

How to specify a foreign key?

i.e. Post model has a column poster_id and for posters I'm actually using User model. Obviously this is a User has_many Posts relationship, but how to I specify that poster_id is actually an id to User model?
Use foreign_key option:
has_many :posts, :foreign_key => :poster_id
For Post model it will be
belongs_to :user, :foreign_key => :poster_id
or
belongs_to :poster, :class_name => 'User'

How to access referenced table in a n:m relation in Ruby on Rails?

I have got a Database like this:
users
-id
user_cars
-user_id
-car_id
cars
-id
-model
-color
So a user can have multiple cars, and detailed information about the cars are in a big cars table. I also created the models with the relationships.
class User
has_many :user_cars
class User_car
belongs_to :user
belongs_to :cars
class Car
has_many :user_cars
Now I want to access the information for all the cars for one user. My first approach would be to get at least one information (i.e. color) from the cars table.
I tried this one, just as an example for accessing the middle table:
#user_id = current_user.user_cars.find(1).user_id
works! But when I try to access the cars table I always get an error.
#color = current_user.user_cars.cars.find(1).color
undefined method `cars' for #<ActiveRecord::Relation:0xaf92e8c>
So I think Im doin something easy very wrong...
When I know how to get access to the third table, I have to do it in that fashion, that I only get results for the user and not just only the first entry, maybe you guys can help me with that aswell. Thanks!
The issue in your example by the way is that belongs_to should be singular. Also, your order was wrong.
#color = current_user.user_cars.find_by_car_id(1).car.color
You should rewrite this to use a has_many through association:
class User
has_many :user_cars
has_many :cars, :through => :user_cars
class UserCar
belongs_to :user
belongs_to :car
You can then access the cars by doing:
current_user.cars
And the color by doing:
#color = current_user.cars.find_by_car_id(1).color
EDIT
After some debugging, it turns out that the Car model has a class property. Class is a reserved word in ruby. Be careful with naming your attributes!
Without has_many :through associations:
#color = current_user.user_cars.where(:car_id => 1).first.color
With them:
class User < ActiveRecord::Base
has_many :user_cars, :foreign_key => :user_id, :class_name => "UserCar", :inverse_of => :user
has_many :cars, :through => :user_cars
end
class UserCar < ActiveRecord::Base
belongs_to :user
belongs_to :car
end
class Car < ActiveRecord::Base
has_many :user_cars, :foreign_key => :car_id, :class_name => "UserCar", :inverse_of => :car
has_many :cars, :through => :user_cars
end
#color = current_user.cars.find(1).color
http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association
:through defines a shortcut
:inverse_of defines a method (association) which represents current model in :class_name model
:class_name defines which model should be represented by :user_cars
:foreign_key tells which column in the target model's table represents current model (in table user_cars (or users_cars, depends on how you define the association, i think it should be user_cars in this example.. and users_cars for has_and_belongs_to_many)
Details on those are in the link above.

Resources