Помогите с запросом ActiveRecord - PullRequest
1 голос
/ 10 марта 2011

Модели:

class User < ActiveRecord::Base
  has_many :attendances
  has_many :courses, :through => :attendances
end

class Course < ActiveRecord::Base
  has_many :attendances
end

class Attendance < ActiveRecord::Base
  belongs_to :user
  belongs_to :course
end

Миграции:

create_table(:users) do |t|
  t.string :name
end

create_table(:courses) do |t|
  t.string :name
end

create_table(:attendances) do |t|
  t.references :user, :course
  t.date :date
end

Вопрос

Я хотел бы запросить:

  • список всех курсов
  • дата последнего посещения данного пользователя (если есть) для каждого курса

Каков наилучший способ связать следующее водин запрос?

@courses = Course.all
@user = User.first
@attendances = @user.attendances.group('course_id').order('date DESC')

Обратите внимание, что существует требование включать курсы, которые пользователь еще не посещал.

Любой совет, который высоко ценится.

Обновление

Результат, который я ищу, выглядит следующим образом:

Course            Last attended
===============================
Some course       2011-03-09
More training     Not Attended
Another course    2010-12-25

В SQL я написал бы этот запрос как:

SELECT * FROM courses AS c
LEFT OUTER JOIN attendances AS a ON a.course_id=c.id
WHERE a.user_id=1
GROUP BY a.course_id
ORDER BY a.date DESC;

Я всегда могвыполнить этот SQL изнутри Rails, но я бы предпочел избежать этого и, если это возможно, делать что-то «по пути Rails».

Ответы [ 2 ]

1 голос
/ 10 марта 2011

«Rails-Way» предназначен для определения небольших искателей в модели, а затем для их цепочки в контроллерах.

В классе Attendance вы можете определить новый метод

def self.last_attendance
  maximum("date")
end

В классе Corse ...

def self.ordered
  order("name DESC")
end

И так далее.В контроллере вы используете их в разных комбинациях.Большим преимуществом этого подхода является

  • Возможность повторного использования методов поиска
  • Разделение классов
  • Лучшая читаемость кода
1 голос
/ 10 марта 2011

Ваше отношение has_many должно быть таким:

  class User < ActiveRecord::Base
    has_many :attendances
    has_many :courses, :through => :attendances
  end

  class Course < ActiveRecord::Base
    has_many :attendances
    has_many :users, :through => :attendances
  end

  class Attendance < ActiveRecord::Base
    belongs_to :user
    belongs_to :course
  end

И, пожалуйста, объясните вашу проблему.Потому что

@user.courses will give you only related courses
Course.all will give you all courses

Отредактировано:

Course.find(:all, :joins => 'LEFT OUTER JOIN attendances ON attendances.course_id = 
courses.id', :conditions => ['attendances.user_id = ?', 1], :group => 
'attendances.course_id', :order => 'attendances.date DESC')

Надеюсь, это сработает для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...