2015-05-12 2 views
1

Мы пытаемся установить лучшие практики для проекта, и мы обсуждаем, где должны быть размещены методы SQL и ActiveRecord.Ruby on Rails Соглашения ActiveRecord

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

Так что с чем-то упрощенно, как:

client = Client.find(10) 

бы это в идеале жить в модели или контроллер? Я понимаю, что это может не сильно повлиять, и ответ будет неважен, но любое понимание вопроса было бы замечательным.

+3

'client = Client.find (10)' - довольно простая операция и немного вне контекста, поэтому я бы сказал, что он может попасть в контроллер или модель в зависимости от того, почему это делается. Без каких-либо других указаний, я бы сказал, контроллер. Соглашение предназначено для того, чтобы контроллер и представления были легкими для кода, а код - в моделях (и просмотр кода помощи в помощниках), но это * соглашение * (не абсолютное правило), которое есть по какой-либо причине, что что много кода связано с сортировкой, сортировкой и обработкой данных, что связано с моделью. Контроллер может иметь * некоторый * код.:) – lurker

+1

Это была дискуссия, которая вытекала из чтения этого из блога: «Сложные запросы (т. Е. Более сложные, чем простая находка), вообще говоря, вы никогда не должны использовать метод where или любые другие методы построения запросов как и за пределами самого класса модели ». Что я сейчас понимаю, он говорит, что находки можно использовать в контроллере, так что как насчет Client.where («first_name = 'Carly») Я предполагаю, что это должно быть вне контроллера? – CarlyL

+3

Для 'Client.where (" first_name = 'Carly' ")', я бы все равно сказал * это зависит * (по контексту). :) – lurker

ответ

1

Существует не один хороший ответ на это, и у меня есть ощущение, что это может быть закрыто из-за этого, но здесь все равно.

Client.find(10) и Client.where("first_name='Carly'") примерно так же просты, как вы можете это сделать. Вы просто не можете заменить первый методом модели. Второй, я полагаю, вы можете сделать метод search, но это может быть преждевременным.

Я думаю, что точка этих статей является то, что вы не хотите что-то вроде этого в контроллере:

Client.where("created_at > X").where("some_flag = true").order('created_at DESC')

Это довольно четкий кандидат на имени сферы (или несколько из них).

Это говорит о том, что я буду оставлять это в своем контроллере, потому что он невероятно специфичен для этого контроллера и не будет использоваться где-либо еще (когда-либо), поэтому в DRYing его IMHO не так много смысла.

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

+0

Я думаю, что это ядро ​​того, что мы искали. Спасибо, что нашли время ответить! – CarlyL

1

За исключением класса scope s, вы также можете рассмотреть наличие моделей, которые извлекают запросы как с обеих моделей, так и с контроллеров.

Посмотрите, как Gitlab handles it.

+0

Спасибо, Андрей, я раньше не слышал о поисковых моделях. Это интересная концепция, я ценю отзывы. – CarlyL

1

Я действительно считаю, что «основные» принципы здесь СУХОЙ и КИСС.

Если у вас относительно длинный запрос (несколько статей where, join и т. Д.), Которые требуются несколькими вашими контроллерами, извлеките его как область действия.

Если у вас довольно длинный запрос, который, казалось бы, перегружает весь метод контроллера, вы должны, вероятно, извлечь его как область.

+0

Спасибо арт. Я думаю, что стало понятнее, как мы должны обрабатывать простые и не простые методы ActiveRecord и абстрагироваться от сферы действия. – CarlyL

+0

Добро пожаловать @CarlyL. Рад, что смог помочь. Удачи! –

Смежные вопросы