I have three tables User, User_types and Purchases.
user: id etc
user_purchase_types: id, typename, user_id
purchases: id, user_id, user_purchase_type_id, note
Users can have any number of purchases and user_types. A purchase can have one user_purchase_type.
Users can log in, create types, do purchases etc - this all works fine
However I want, when listing purchases, to see the user_purchase_types.typename, rather than the id number. Simple I think, use belongs_to, they already have the right id fields, should just work. But it doesn't
I have tried a million variations of belongs_to, has_many , has_many through etc etc but cannot get the right relationship and so show the typename rather than the id.
There are the right foreign_key id fields in the tables so this should work.
When listing the purchases in the purchase controller I use @purchase = current_user.purchases. When looping this to display in the view I think I should be able to use purchase.user_purchase_type.typename but this gives me a 'NoMethodError'.
What am I doing wrong or should I just denormalise the DB and have done with it?
EDIT Models as req
class UserPurchaseType < ActiveRecord::Base
belongs_to :user
belongs_to :purchase
attr_accessible :typename, :id
end
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :purchases, :dependent => :destroy
has_many :user_purchase_types, :dependent => :destroy
end
class Purchase < ActiveRecord::Base
belongs_to :user
has_many :user_purchase_types
attr_accessible :date, :user_purchase_type_id, :note
end
index.erb file
<% @purchases.each do |purchase| %> #this works
<tr>
<td><%= purchase.user_purchase_type.typename %></td> #this fails
<td><%= purchase.date %></td>
<td><%= purchase.note %></td>
</tr><p>
<% end %&开发者_开发技巧gt;
purchase controller
def index
@user_purchase_types = current_user.user_purchase_types # this works
@purchases = current_user.purchases #this works
You just need to add foreign key in your existing association.
class Purchase < ActiveRecord::Base
belongs_to :user
has_many :user_purchase_types, :foreign_key => 'user_purchase_type_id'
attr_accessible :date, :user_purchase_type_id, :note
end
there is a one to one relationship between them rgt? yes you should be able to be able to access typename, but by using @purchase.user_type.typename. and not purchase.user_type.typename.
and would be better if you could show user models too.
and is current_user defined?
also you can try by finding out the usertype first and then access it: @user_type = UserType.find(@purchase.user_type_id) @user_type.typename
You should always try the relationships first on console and see if your getting it rgt
Your relationships are all messed up. You have a one to many relationships between purchases and user purchase type. and therefore you can not use @purchase.user_purchase_type.typename You have to use
@purchase.user_purchase_types.each do |i|
i.typename
end
class Purchase < ActiveRecord::Base
belongs_to :user
has_many :user_purchase_types
attr_accessible :date, :user_purchase_type_id, :note
end
The Purchase
-> UserPurchaseType
association is a has_many
relationship but you seem to be trying to use it with user_purchase_type_id
which would indicate a belongs_to :user_purchase_type
relationship, but your association is has_many :user_purchase_types
It sounds like you may want something like:
<% @purchases.each do |purchase| %> #this works
<tr>
<td><%= purchase.user_purchase_types.collect(&:typename).join(',') %></td>
<td><%= purchase.date %></td>
<td><%= purchase.note %></td>
</tr><p>
<% end %>
to list all your UserPurchaseType
typename
's, comma separated.
If you do this, make sure when you load your @purchases
in the controller to also include a .includes(:user_purchase_types)
. This will eager load the association and avoid rails loading each UserPurchaseType
as you iterate through.
精彩评论