2016-10-25 2 views
0

Как вы решаете, что строку кода нужно перенести из контроллера в модель?Вопросы о Fat-Model, практике Skinny-Controller

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

  1. любая логика неответ связанных должны идти в модели
  2. вам нужно только параметры запроса процесса и инициализировать слой модели в контроллерах должны быть реализованы в модели слоя
  3. Бизнес-логика

EDIT: Скажем, я хочу, чтобы реорганизовать мой контроллер ниже от:

class TaskController < ApplicationController 
    def index 
    @tasks = Task.find_all_by_complete(:false, :order => "created_at DESC") 
    end 
end 

в

class TaskController < ApplicationController 
    def index 
    @tasks = Task.find_incomplete 
    end 
end 

Какой из этих 2-х блоков кода являются правильными?

class Task < ActiveRecord::Base 
    def self.find_incomplete 
    find_all_by_complete(:false, :order => "created_at DESC") 
    end 
end 

или

class Task < ActiveRecord::Base 
    def find_incomplete 
    self.find_all_by_complete(:false, :order => "created_at DESC") 
    end 
end 

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

@average_review = @surf_school.surf_school_reviews.average(:rating).round(2) 

в

@average_review = @surf_school.average_review 

мой код внутри модели должно быть:

def average_review 
    self.surf_school_reviews.average(:rating).round(2) 
end 

ответ

1

Как правило, в качестве отправной точки я бы поместил любой код, связанный с CRUD в Модели. Настройка пользовательских методов в ваших моделях, чтобы вы могли позвонить @user.invalidate или @post.replace_owner(@user). Эти экземпляры @user можно указать в модели как self. Пример:

class Post < ApplicationRecord 
    def add_owner(user) 
    self.update_attributes(user_id: user.id) 
    end 
end 

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

Edit: Я хотел бы также пойти с первым блоком кода:

def self.find_incomplete 
    find_all_by_complete(:false, :order => "created_at DESC") 
end 

Это точно как создать сферу ActiveRecord вручную, который identicle к следующему:

class Task < ActiveRecord::Base 
    scope :find_complete -> { find_all_by_complete(:false, :order => "created_at DESC") } 
end 

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

Подробнее см. На ActiveRecord::Scoping.

+0

см. Мой EDIT – boholdyjeramae

+0

Я редактировал свое сообщение выше. – meshpi

+0

Итак, первый и второй блоки оба правильные? – boholdyjeramae

0

В моей работе у нас есть несколько классов для каждой модели в слое модели. Для упрощения вещей у нас есть объект DTO и DAO.DTO содержат поля и DAO содержат методы для сохранения, изменения и удаления записи в базе данных.

Некоторые из наших DAO также содержат вспомогательные методы со специальными/более сложными поисковыми запросами и переопределяют стандартные методы сохранения, чтобы предотвратить ввод контроллером недействительных данных в наши модели.

Наши действия контроллера заполняют модели с использованием DAO до определенной точки и сохраняют их новое состояние в базе данных. Наши контроллеры содержат бизнес-логику, но у некоторых DAO есть методы, которые делают немного больше, чтобы предотвратить недействительные данные при выходе из базы данных. Это делает бизнес-логику более понятной и понятной.

Также следует иметь в виду, что это идеально, если вы будете следовать определенной практике, но подумайте о том, чтобы идти боком, если это не соответствует вашим требованиям. Например, если у вас есть бизнес-логика, которая обязательна для выполнения перед каждым действием сохранения, я бы честно либо определил класс utility/helper, у которого есть статический метод, поддерживающий эту логику, либо переопределяющий метод сохранения вашего объекта модели и перемещение там.


Примечание: DAO означает объект доступа к данным. Это распространено в нашем прецеденте, но у вас будет только один класс, который в основном делает то же самое, вместо того, чтобы иметь несколько классов. Это был образец дизайна, который был выбран до того, как я даже начал работать здесь.


Редактировать: Я бы выбрал второй вариант. Но этот пост может помочь вам еще больше: What does def `self.function` name mean?

+0

см. Мой EDIT – boholdyjeramae

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