Разделение проблем в Rails - PullRequest
1 голос
/ 06 июля 2010

Я пытаюсь сделать запись для моего приложения rails и у меня есть некоторые дилеммы по поводу философии, используемой в rails. Мое приложение имеет Link модель, которая has_many Hit s:

class Link < AR::Base
  has_many :hits
end

class Hit < AR::Base
  belongs_to :link
end

Теперь при каждом обращении к ссылке я вызываю метод hit!, чтобы записать запрос по ссылке (чтобы сохранить контроллер в скине, я делаю модель жирной):

class LinksController < ApplicationController
  def hit
    link = Link.find(params[:id])
    link.hit!(request)
  end
end

class Link < AR::Base
  def hit!(request)
    params = extract_data_from_request(request)
    hits.create(params)
  end
end

Теперь вот где я запутался. Я хочу записать данные, которые пришли с объектом request (например, удаленный ip, реферер, пользовательский агент и т. Д.), Поэтому мне нужно передать объект запроса в модель, но я считаю, что это не соответствует разделению интересов "и стирает границы ответственности в схеме проектирования MVC (конечно, поправьте меня, если я ошибаюсь). Также, если я создам Hit объект в самом контроллере, то я делаю тощую модель и толстый контроллер:

class LinksController < ApplicationController
  def hit
    hit_params = extract_data_from_request(request)
    Hit.create(hit_params.merge(:link_id => params[:id])
  end
end

Хотя в последнем случае тестирование значительно упрощается (мне не нужно имитировать запрос в спецификациях моделей) - оно просто кажется неправильным.

Любой совет по этому поводу - высоко ценится.

P.S. extract_data_from_request(req) метод размещается в соответствующих местах, где это необходимо. Возвращает хэш необходимых атрибутов для Hit объекта.

Ответы [ 2 ]

2 голосов
/ 06 июля 2010

Да, я бы согласился с Джоном. Концепцией запроса обычно является «вещь контроллера», но в этом случае ваша модель моделирует запрос, поэтому в данном случае она определенно находится на территории модели. Фактически, когда объект запроса пересекает границу между контроллером и моделью, это просто еще один объект, без особых свойств: он больше не связан с процессом получения и ответа на html-запросы, это просто объект, с которым вы можете делать все, что захотите.

Однако следует опасаться, что в ruby ​​аргументы передаются по ссылке. Это означает, что объектом запроса, которым вы манипулируете в своей модели, является тот же объект, который обрабатывается в контроллере. Я могу быть слишком параноиком (или просто ошибаться), но вы можете захотеть передать его копию модели, а не самому запросу. т.е.

class LinksController < ApplicationController
  def hit
    link = Link.find(params[:id])
    link.hit!(request.dup)
  end
end
2 голосов
/ 06 июля 2010

Лично я бы опасался слишком обдумывать эти вещи.

Концепция хита очень сильно связана с веб-сайтом или веб-приложением, как и концепция (HTTP) запроса.Анти-шаблон толстого контроллера больше связан с длительными действиями контроллера, которые содержат операторы ActiveRecord find и бизнес-логику (часто характеризуемую блоками if / elsif / else), которые можно легко извлечь в модель.

Контроллеры имеют определенные обязанности по оркестровке.Создание объекта в одном не является отвратительным преступлением.В конце концов, мы делаем это все время в наших create действиях.

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