Ege Ersoz
Ege Ersoz

Reputation: 6571

Parameter not being passed to partial

I have a Rails 4 application where user accounts can be created in two ways: by new users (sign up) or by admin users (add account).

My thought process was to send all requests to the new action in the User controller, have some logic in there to see if it's a new user or an admin user and handle the request accordingly. Here's my template:

new_by_admin.html.erb:

<%= form_for(@user) do |f| %>
    <div class="col-md-6 col-md-offset-3">
        <h1 class="centertext">Add User</h1>
        <%= render 'add_user_fields', f: f %>

        <%= f.submit "Create account", class: "btn btn-large btn-primary" %>
    </div>
<% end %>

In the controller, this works fine:

user_controller.rb:

def new
    @user = User.new
    if !signed_in?
        @user.confirmation_code = User.new_confirmation_code
    elsif signed_in? && current_user.admin?
        new_by_admin
    else
        redirect_to root_url
    end
end

def new_by_admin
    @user = User.new
end

However, the below code throws a "First argument in form cannot contain nil or be empty" error in the template, presumably because @user is nil.

def new
    @user = User.new
    if !signed_in?
        @user.confirmation_code = User.new_confirmation_code
    elsif signed_in? && current_user.admin?
        render 'new_by_admin', user: @user
    else
        redirect_to root_url
    end
end

What is the difference between these, and why doesn't the second method work even though I'm passing the @user object as a parameter to the partial?

Upvotes: 0

Views: 66

Answers (2)

Ege Ersoz
Ege Ersoz

Reputation: 6571

I figured it out. While looking at the terminal on the server, I noticed that the requests were being sent to users#new_by_admin. So it was a problem in the routes.rb file. I had the route defined like this (from earlier attempts):

get '/adduser', to: 'users#new_by_admin', as: 'add_user'

Changing this to:

get '/adduser', to: 'users#new, as: 'add_user'

Made it work. I don't fully understand why, since the user object was initiated inside the new_by_admin method as well, but it works now. I also changed the render line in the OP to the below as per stakechaser's suggestion:

render :new_by_admin

Upvotes: 0

steakchaser
steakchaser

Reputation: 5249

render allows you to instruct a contollers action to render a different view than the default that matches the action name (new in your case). When the specified view is rendered it has access to any of the instance vars set by the action. There's no need to pass anything as a param (I'm not even sure that's possible).

Instead, just use: render :new_by_admin

Upvotes: 1

Related Questions