Rails где с join, но вернуть объект parent? - PullRequest
1 голос
/ 16 октября 2011

Предположим, у меня есть класс, представляющий список фильмов, принадлежащих пользователю:

class User < ActiveRecord::Base
    has_one :movie_list
end

class MovieList < ActiveRecord::Base
    belongs_to :user

    has_many :movie_list_movie_relationships
    has_many :movies, :through => :movie_list_movie_relationships
end

class Movie < ActiveRecord::Base
    has_many :movie_list_movie_relationships
    has_many :movie_lists, :through => :movie_list_movie_relationships
end

class MovieListMovieRelationship < ActiveRecord::Base
    belongs_to :movie
    belongs_to :movie_list
end

Есть ли способ создать метод MovieList, который возвращает MovieList, содержащий только фильмы, например, сКонкретный год выпуска.Я хочу что-то вроде:

class MovieList < ActiveRecord::Base
    ....
    def for_year year
        movies.where(:year => year)
    end
end

ЗА ИСКЛЮЧЕНИЕМ, что я хочу, чтобы результатом был сам MovieList, тогда как это возвращает массив Movies.Так что я мог бы сделать, например:

list = User.first.movie_list.for_year(1999)
list.id # would give the id of the MovieList = User.first.movie_list.id
list.movies.first.id # would give the id of the first movie in list

У меня такое чувство, что я либо а) столкнулся с этой проблемой, потому что у меня плохой дизайн, и было бы здорово, если бы кто-то мог объяснить, как я должен спроектировать это, или б) просить что-то относительно обыденное, но я просто не знаю правильной терминологии.

Спасибо!

Редактировать

У меня есть конкретные причины, по которым нужно MovieList, а не массив Movie s.Например, я написал вопрос с User has_one :movie_list, но на самом деле User has_many :movie_lists (например, «Фильмы, которые у меня есть на DVD», «Фильмы, которые я хочу посмотреть» и т. Д.).Вот почему я не просто использую простое соединение между User и Movie.Я хочу MovieList, потому что я хочу, чтобы id списка передавался, чтобы было легко добавить фильм в определенный список;У меня есть MovieListMovieRelationshipController.Я думаю, что мне в конечном итоге придется выбрать фильмы в виде массива и просто передать идентификатор списка вручную.

Изменить 2

Вотчто я в итоге делал, согласно @normalocity и последующим комментариям.Любые дальнейшие комментарии / предложения приветствуются:)

class MovieList
    ...
    def limit_to_year year
        new_list = MovieList.new(self.attributes)
        new_list.id = self.id
        new_list.movies = []

        limited_movies = movies.where(:year => year)
        new_list.movies = limited_movies
        return new_list
    end
end

1 Ответ

2 голосов
/ 16 октября 2011

Вы не можете делать то, на что надеетесь напрямую, нет, но достаточно просто создать пустой MovieList, а затем добавить массив фильмов из вашего метода for_year в новый MovieList. Вы даже можете сделать запрос для массива связанных Movie объектов быстрее / проще с помощью named_scope.

В Movie класс:

named_scope :for_year, lambda { |year| {:conditions => ["year = ?", year]} }

Теперь, каждый раз, когда вы звоните Movie.for_year("1945"), вы получаете массив объектов Movie того года.

Тогда ...

  • Создайте новый MovieList (который принадлежит НЕТ пользователю) и добавьте результаты из # 1 в список

Это может сработать: movies1945 = MovieList.create(:movies => Movie.for_year("1945")

Если это не сработает, вам, возможно, придется разделить создание нового объекта MovieList и присвоение значений коллекции Movie.

Если вам нужно различить простой список фильмов (в чем разница между этим и массивом, я не знаю, но если это различие необходимо), и Movies, который имеет конкретный пользователь в своем коллекции, тогда вы можете разделить ваши классы на MovieList (просто список фильмов) и Collection (фильмы, которые есть у данного пользователя).

Если вам это не нужно, то в списке фильмов 1945 года может быть пользователь nil, или (скажем, ваш веб-сайт называется imdb.com ), вы можете создать фиктивную учетную запись пользователя. называется "imdb", и список принадлежит этому пользователю.

...