ROR: выберите из нескольких таблиц с .each сделать - PullRequest
1 голос
/ 11 декабря 2010

У меня есть три таблицы: 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

, но в итоге сохраняется только последнее сопоставленное событие.Где я сделал не так?

Ответы [ 3 ]

3 голосов
/ 11 декабря 2010

Во-первых, краткосрочное решение:

@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

Чтобы заставить работать вышеперечисленное, вам нужно сделать 2 вещи:

  1. правильно установите ваши ассоциации.Похоже, вам нужна has_many :through ассоциация :

    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
    
  2. настройка вложенных маршрутов ресурсов в config/routes.rb:

    resources :users do
      resources :events
    end
    

Я настоятельно призываю вас взглянуть на долгосрочное решение.Если вы используете краткосрочное решение, вы упускаете большую часть преимуществ, которые может предложить rails!

0 голосов
/ 11 декабря 2010

Что пошло не так?

@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    

Кроме того, как отмечали другие, это не самый лучший / хороший способ сделать это.

0 голосов
/ 11 декабря 2010

Составьте карту вместо каждой:

@event_names = @temp.map do |t|
   Event.where(:id => t.event_id).all
end

Но @bowsersenior прав: используйте правильные отношения, чтобы рельсы делали правильные вещи. Также более эффективен, потому что он будет делать только 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...