我有三个表:users,events和user_events,然后我在控制器中执行以下操作:
@temp = UserEvent.where(['user_id = ?', session[:uid]]).all
@temp.each do |t|
@event_names = Event.where(['id = ?', t.event_id]).all
end
但它最终只保存最后一个匹配的事件。我哪里做错了?
答案 0 :(得分:3)
首先,短期解决方案:
@event_names = UserEvent.where(['user_id = ?', session[:uid]]).all.map do |t|
Event.where(['id = ?', t.event_id]).all
end.flatten
现在,长期解决方案:
@user = User.find(params[:id])
@user.events
要实现上述目标,您必须做两件事:
正确设置关联。看起来您需要has_many :through
association:
class User
has_many :user_events
has_many :events, :through => :user_events
end
class UserEvent
belongs_to :user
belongs_to :event
end
class Event
has_many :user_events
has_many :users, :through => :user_events
end
在config/routes.rb
中设置nested resource routes:
resources :users do
resources :events
end
我强烈建议您考虑一下长期解决方案。如果您采用短期解决方案,那么您将失去rails提供的许多好处!
答案 1 :(得分:0)
做一张地图,而不是每张地图:
@event_names = @temp.map do |t|
Event.where(:id => t.event_id).all
end
但@bowsersenior是对的:使用适当的关系让rails做正确的事。效率也更高,因为它只会执行2次查询而不是N + 1。
class UserEvent < ActiveRecord::Base
belongs_to :user
belongs_to :event
end
class User < ActiveRecord::Base
has_many :user_events
has_many :events, :through => :user_events
end
@events = User.find(session[:uid]).events
@event_names = @events.map(&:name) # for example
答案 2 :(得分:0)
出了什么问题?
@temp.each do |t|
@event_names = Event.where(['id = ?', t.event_id]).all # will reassign @event_name each time
end
每次循环时都会重新分配变量@event_names,因此@event_names将保留的唯一值来自最后一次循环。
你应该做什么:
@temp.each do |t|
@event_names.push(Event.where(['id = ?', t.event_id]).all) or
end
另外,正如其他人所指出的,这并不是最好/最好的方法。