Где я должен положить этот код? - PullRequest
0 голосов
/ 03 марта 2011

Мои настройки: Rails 2.3.10, Ruby 1.8.7

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

Ответы [ 3 ]

2 голосов
/ 03 марта 2011

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

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

params[:models] = { id_of_instance_1 => { :attribute => value }, 
                    id_of_instance_2 => { :attribute => value2 },
                  }

Вы можете довольно легко выполнить групповое обновление на вашем контроллере с помощью:

Model.update(params[:models].keys, params[:models].values)

Может помочь дополнительная информация о деталях, которые вы обновляете и откуда они берутся.


РЕДАКТИРОВАТЬ: После прочтения вашего ответа ниже ...

Есть несколько способов сделать это. Вы можете реализовать Model.win и Model.lose как методы класса для включения логики, а затем просто вызвать эти методы из вашего контроллера:

def process_outcome
  @winner = Model.win(params[:winning_id])
  @loser = Model.lose(params[:losing_id])
end

Или даже как единственный вызов метода:

def process_outcome
  # passing the entire params hash to `process_outcome` which returns an array
  @winner, @loser = Model.process_outcome(params)
end

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

Однако, если вы добавляете в класс различные классы, возможно, стоит объединить их в отдельный объект:

# app/controllers/models_controller.rb
def process_outcome
  @outcome_processor = OutcomeProcessor.new(params)
  @winner = @outcome_processor.winner
  @loser  = @outcome_processor.loser
end

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

0 голосов
/ 03 марта 2011

Это почти наверняка должно идти в модели, а не в контроллере.

Я думаю, что это должно идти в методе экземпляра, а не в методе класса.Моя причина в том, что вы, вероятно, будете звонить по URL /model/id/action?other_model_id=other_id.Тогда из этого следует, что в действии контроллера вы получите соответствующий экземпляр модели для id, а также other_id, но поскольку это путь для модели id, а не для модели other_id, вы 'd call @id_model.perform_action(@other_id_model).

Надеюсь, это имеет смысл.

0 голосов
/ 03 марта 2011

Я думаю, вы должны следовать традиции. :) Вы можете использовать другой класс (не контроллеры) для написания метода транзакции.

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