开发者

Rails linked tables belongs_to or has_many not working

开发者 https://www.devze.com 2023-04-08 18:50 出处:网络
I have three tables User, User_types and Purchases. user:idetc user_purchase_types: id, typename, user_id

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号