I'm doing a small experiment and trying to extract some logic from controller's action.
I have code like this:
Controller
def create @user = User.new(user_params) if @user.save redirect_to user_url(@user), notice: 'Welcome to MyApp' else render :new end end And try to create something like this:
Controller
def create user_service.display end private def user_service RenderService.new(self) end Separate Service object
require 'forwardable' class RenderService extend Forwardable delegate [:params, :user_url, :redirect_to, :render] => :@obj attr_reader :obj, :user def initialize(obj) @obj = obj @user = User.new(user_params) end def display redirect_to(user_url(user), notice: 'Welcome to MyApp') if user.save render(:new) unless user.save end private def user_params params.require(:user).permit(:name, :email, :password, :confirmation) end end Form for creating new user
= simple_form_for(@user, html: { }) do |form| = form.input :name, required: true = form.input :email, required: true = form.input :password, required: true = form.input :confirmation, required: true = form.submit 'Create my account', class: 'btn btn-primary' As you can see all I tried to do is to encapsulate logic into a separate class, but I got an error from ActionView::Template::Error for some reason and the error says undefined method 'model_name' for nil:NilClass.
I really don't understand why it does not work. To me it looks like I sent the same message to the same object and it should work just fine, but it doesn't.
Second question: why is ActionView involved here?
Thank you for any explanation.
Oh, by the way, if you know the code responsible for such behavior and where it lives in the Rails repository please point me to it.
Thanks in advance. :)