Методы, которые помогают находить данные в БД, такие как «find», «find_by», «where» и т. Д., Принадлежат модели или контроллеру в ruby ​​на рельсах? - PullRequest
1 голос
/ 20 февраля 2012

Я закончил личный проект, сейчас просто прохожу мой код, убирая вещи. Мне интересно, принадлежат ли методы, которые помогают найти вещи в базе данных, в модели?

* 1003 Е.Г. *

Это было в моем контроллере:

@user = User.find_by_username(username)

Затем я переместил его в свою модель:

class << self
    def find_user_by_username(username)
      User.find_by_username(username)
    end

end

добавил это в мой контроллер:

@user = find_user_by_username(username)

Что-то не так с этим? действительно ли имеет значение, если у меня есть find, где и другие методы, которые помогают найти вещи в моем контроллере? Как насчет того, чтобы поместить их в помощников?

Другое дело, что я пытался вызвать тот же метод в действии show и передать в параметрах имя пользователя в качестве значения. Я получаю:

undefined method `find_user_by_username' for #<UsersController:0x000001034a6060>

Я просто хочу очистить, но не ломать вещи. Я не понимаю, почему этот метод работал бы хорошо в моем новом действии, но не в действии показа.

Заранее спасибо

С уважением

Ответы [ 4 ]

1 голос
/ 20 февраля 2012

В хорошем дизайне вы хотите иметь самый тонкий из возможных контроллеров, а это означает перемещение максимум кода из контроллера в модель. Затем, если ваша модель становится слишком большой, есть другой метод для перемещения кода вниз по модели на другие уровни (библиотеки, наблюдатели и т. Д.).

Метод find_by_ * уже есть в модели, но это метод класса. Поэтому вполне разумно позвонить с вашего контроллера.

Если ваш поиск был не простой находкой, а, скажем, поиском по user.username or user.company.name, то вам, вероятно, придется создать этот метод поиска в модели и вызвать его из вашего контроллера.

Этот способ также позволяет вам вызывать этот метод из другого контроллера вместо копирования / вставки его

Более подробную информацию о том, где разместить свой код, можно найти здесь: http://qualityonrails.com/archives/33

1 голос
/ 20 февраля 2012

Контроллер является идеальным местом для вызовов методов вашей модели. Хотя не идеальное место для логики модели.

Подсказка: идеальное место для этого начинается с буквы «М» и заканчивается буквой «одель».

Контроллер должен позвонить User.find_by_username. Не должно быть никакого метода find_by_username для самого контроллера, потому что это один уровень абстракции слишком много и «скрывает», что именно делает метод find_by_username.

Вызовите метод модели из вашего контроллера. Вы одержимы уборкой, когда вам это не нужно.

0 голосов
/ 20 февраля 2012

Причина, по которой вы получаете неопределенную ошибку метода, состоит в том, что то, что вы определили, все еще является методом класса, поэтому вам нужно вызывать его так:

@user = User.find_user_by_username(username)

Однако вы заметите, что это не так.на самом деле не лучше, чем:

@user = User.find_by_username(username)

В общем, я чувствую, что простой find(id) или find_by_xxxx(xxxx) можно использовать в контроллере, но в модель следует перенести более продвинутую логику,Например, если у вас есть что-то вроде User.where(:activated => true).where("created_at > ?", Date.today - 1.week), вы, вероятно, захотите, чтобы это было перемещено в вашу модель User по методу find_recent_users или что-то в этом роде.

0 голосов
/ 20 февраля 2012

Ваш исходный код в порядке, только при запуске методов цепочки в запросах необходимо учитывать рефакторинг.

, т.е. рефакторинг этого

User.where(:age => 0..25).where(:owns_a_dog => true).includes(:dogs) в User.young_dog_owners

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