开发者

specify columns from has many through association Rails

开发者 https://www.devze.com 2023-02-17 21:24 出处:网络
I have three models. User has_many :boards through => :celebrations has_many:celebrations, :dependent => :destroy

I have three models.

User
has_many :boards through => :celebrations
has_many   :celebrations, :dependent => :destroy

Board
has_many   :celebrations, :dependent => :destroy
has_many  :users, :through => :celebrations do
           def by_role(role) 
           find(:all, :conditions => ["celebrations.role = ?", role])
           end
           end

Celebration
:belongs_to :user
:belongs_to :board

Celebration Table

   create_table :celebrations do |t|
      t.column :board_id,        :int, :null => false
      t.column :user_id,         :int, :null => false 
      t.column :role,            :string,  :null => false
      t.column :token,           :string
      t.column :accepted,    :boolean, :default => false
      t.timestamps

In the controller:

  @board = Board.find(ses开发者_Python百科sion[:board_id])
    @friends = @board.users.by_role("FRIEND")

In the view:

<% for friend in @friends do %>
<%= friend.name %>
<%= friend.email %>

However when I do the following:

<% friend.celebration.accepted %> 

I get the following error:

undefined method `celebration' for #<User:0x104788c00>

How can I access the column 'accepted' in the celebrations table returned along with the record using the model extension "by_role(role)".

Thank you for your help in advance.


You can eager load the celebrations like this:

Board model:

Board
  has_many   :celebrations, :dependent => :destroy
  has_many  :users, :through => :celebrations do
     def by_role(role) 
       find(:all, :conditions => ["celebrations.role = ?", role], :include => :celebrations)
     end
  end

With :include you will have one more hit:

Celebration Load (0.2ms) SELECT celebrations.* FROM celebrations WHERE (celebrations.user_id IN (5,6)) 

that loads the celebrations data for users. This will avoid in this particular case two hits that would be needed to retrieve celebrations for each user. If you have 10 users you will end with one hit instead of 10.

Eager loading loads all the data you will need to cycle through in association with one query instead of n queries.

The problem remains for the accepted data because you will have an array of celebrations due to the has_many relationship with user.

You can use something like this:

<% friend.celebrations.map{|celeb| celeb.accepted }.join(",") %>
0

精彩评论

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