使用连接表的行存在作为别名

时间:2018-01-03 21:21:25

标签: ruby-on-rails postgresql activerecord arel

给定一个名为Event(id,name)的模型和一个名为EventUser(event_id,user_id)的模型,我迭代了Events。在此迭代期间,我将根据是否存在EventUser来显示登录用户是否正在参加事件。标准的东西。

我知道我可以针对每个事件执行查询,并且具有诸如

之类的内容
class Event < ActiveRecord::Base

  def user_attending?(user)
    event_users.find_by(:user_id => user.id)
  end 

end

但这不是很干净,高效或可扩展。

我可以从事件列表中加载所有用户参加的事件,比如说,

@events = Event.all 
@attending_events = current_user.event_users.where(:event_id => @events.map(&:id))

哪个更好,但不是很好。我可以用这个添加我的事件模型的访问器并遍历@attending_events,但这似乎很蠢。

我想在我理想的情况下,我可以加入events.id = event_users.event_id上的两个表,以及event_users.user_id = current_user.id,如果该行存在,我将能够标记/ a结果列为attending

如何使用Arel或ActiveRecord,甚至SQL?在这里使用PostgreSQL。

3 个答案:

答案 0 :(得分:0)

你想要这样的东西吗?抱歉,幸运的猜测,但如果我不理解你的问题,你能否更具体,你想要解决哪个问题?

class Event < ActiveRecord::Base
  has_many :user_events, class_name: 'UserEvent', inverse_of: :event
  has_many :users, through: :user_events
end

可能的用法

1)建议用法:

Event.joins(:user_events).where(user_events: {user_id: user.id}).any?

2)按用户细节过滤。请注意,joins从事件模型中获取已定义的has_many关系,但where采用表名。以防has_many关系名称和表名不同

Event.joins(:users).where(users: {name: 'Harry'}).any?

3)具体记录的替代用法,而不是来自Rails - check if record exists in has_many association的id

current_event.users.exists?(user.id)

答案 1 :(得分:0)

我在想它可能很简单:

class User < ActiveRecord::Base
  has_many :user_events, class_name: 'UserEvent', inverse_of: :event
  has_many :events, class_name: 'Event'
end

然后你就做了 @attending_events = current_user.events

在您的视图中,您可以为Event current_user所参与的每个--net=host提供所存储的内容。

答案 2 :(得分:-1)

我很困惑。假设:

  • 您已在has_many :events, through: :event_users模型中设置User
  • 你有一个像@user_events = user.events
  • 这样的实例变量(在你的控制器中是可能的)
  • 你有一个实例变量(也可能在你的控制器中),如@events = Event.all

在您看来,并不是(假设erb):

<% @events do |event| %>
  <% if @user_events.include?(event) %>
    ... do some stuff
  <% else %> 
    ... do some other stuff
  <% end %>
<% end %>

也许我是密集的,完全忽视了这一点......如果是这样,请提前道歉。