Moosa
Moosa

Reputation: 3216

Rails 4 Missing Template error

I'm using Rails 4 with Devise for user authentication. I'd like to collect additional inputs from users at a later stage (on another page).

I'm getting a template error and it seems like since I'm using devise, there is some conflict with my user controller. Devise controller actions are in the application controller (lmk if you need this code too)

When I submit the form, here is the template error I get:

Missing template users/update, application/update with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in: * "C:/Users/amoosa/Desktop/mktdemo/app/views" * "C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/devise-3.2.4/app/views"

my routes.rb

devise_for :users

resources :users, only: [:update, :edit]

In app/controllers/users_controller.rb

class UsersController < ApplicationController

  before_filter :load_user

  def update
    @user.update_attributes(user_params)
  end

  private

  def load_user
    @user = User.find(params[:id])
  end

  def user_params
    params.require(:user).permit(:color)
  end
end

In app/views/users/edit.html.erb

<%= render 'form' %>

In app/views/users/_form.html.erb

<%= form_for @user, url: user_path, html: { method: :put } do |f| %>
 <div class="form-group">
  <%= f.label :what_is_your_favorite_color %>
  <%= f.text_field :color, class:"form-control" %>
 </div>

 <div class="form-group">
    <%= f.submit "Submit", class:"btn btn-primary" %>
 </div>

<% end %>

Upvotes: 2

Views: 947

Answers (3)

user1854802
user1854802

Reputation: 388

this is how I did it by copying the devise views andadding stuff to views, model etc

In the application_controller Iadded stuff

class ApplicationController < ActionController::Base
  protect_from_forgery

  rescue_from CanCan::AccessDenied do |exception|
    redirect_to root_url, :alert => exception.message
  end

  before_action :configure_devise_permitted_parameters, if: :devise_controller?

  private

  def configure_devise_permitted_parameters
    registration_params = [:username, :email, :password, :password_confirmation, :role, :currency_id]

    devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :password, :remember_me) }

    if params[:action] == 'update'
      devise_parameter_sanitizer.for(:account_update) { 
        |u| u.permit(registration_params << :current_password)
}
    elsif params[:action] == 'create'
      devise_parameter_sanitizer.for(:sign_up) { 
    |u| u.permit(registration_params) 
  }
    end
  end

end

Model -user

class User < ActiveRecord::Base
   # Include default devise modules. Others available are:
   # :confirmable, :lockable, :timeoutable and :omniauthable
   # add :confirmable for email confirmation 
   devise :database_authenticatable, :registerable, :confirmable, 
           :recoverable, :rememberable, :trackable, :validatable

  has_many :posts, dependent: :destroy
  has_many :comments, dependent: :destroy
  has_many :evaluation_assumptions, dependent: :destroy
  has_many :user_positions, dependent: :destroy
  has_many :user_evaluation_results, through: :evaluation_assumptions
  belongs_to :currency

  validates :username, :role, :currency_id, presence: true
  validates :username,:uniqueness => true

  include RoleModel

  roles_attribute :role

 roles :admin, :user, :guest

end

Then copied copied all te views from Devise which I put in app/views/devise for example here is the one app/views/devise/registrations/edit.html.erb. From memmory username was a field I added as well as currency_id. I also added user avatars (Gravatars).

<% content_for :title, "Drill Investor - #{@current_user.username}" %>
<% content_for :tab_group, "dashboard" %>
<% content_for :tab_id, "dashboard" %>
<div class="breadcrumbs">
  <%= link_to 'Users', edit_user_registration_path %> &raquo; 
  <%= link_to current_user.username %>
</div>
<section>  
  <article class="single">
    <div class="form">
      <%= simple_form_for(resource, :as => resource_name, 
          :url => registration_path(resource_name), 
          :html => { :method => :put, class: 'infogroup' }) do |f| %>
        <div class="infogroup-header">Modify your account</div>        
        <%= f.error_notification %>
        <% if @user.errors.any? %>
          <%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:
          <% @user.errors.full_messages.each do |msg| %>
            <li><%= msg %></li>
          <% end %>
        <% end %> <br />
        <div class="infogroup-body">
          <table border="0" cellpadding="0" cellspacing="0" class="info">  
            <div class="form-inputs">
              <tr>
                <td class="lalign largest_column"><span>email</span></td>
                <td> <%= f.text_field(:email, :required => true, :autofocus => true,
                          class: 'very_largest_column') %></td> 
              </tr>
              <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
                <p>Currently waiting confirmation for: <%= resource.unconfirmed_email %>  </p>
              <% end %>
              <tr>
                <td class="lalign largest_column"><span>username</span></td>
                <td> <%= f.text_field(:username, :required => true, class: 'column') %></td>   
              </tr> 
              <tr>
                <td class="lalign largest_column"><span>Currency to use</span></td>
            <td> <%= f.collection_select(:currency_id, Currency.all, 
                      :id, :name, class: 'data') %></td>
          </tr>
          <tr>
            <td class="lalign largest_column"><span>password</span></td>
            <td> <%= f.text_field(:password, :autocomplete => "off", 
                    :hint => "leave it blank if you don't want to change it", :required => false,
                    type: 'password', class: 'column') %></td>
          </tr>
          <tr>
            <td class="lalign largest_column"><span>password-confirmation</span></td>
            <td> <%= f.text_field(:password_confirmation, :required => false,
                    type: 'password', class: 'column') %></td>  
          </tr>
          <tr>
            <td class="lalign largest_column"><span>current password</span></td>
            <td> <%= f.text_field(:current_password, 
                    :hint => "we need your current password to confirm your changes", :required => true,
                    type: 'password', class: 'column') %></td>
              </tr>
            </div>
          </table>
          <div class="form-actions">
            <%= f.button :submit, "Update" %>
          </div>
        </div>
        <%= render 'user_gravatar' %>        
      <% end %>
      <%= link_to "Back", :back %>
    </form>
 </article>
</section>

Upvotes: 0

Abdul Baig
Abdul Baig

Reputation: 3721

Try to change you update to:

  def update
    respond_to do |format|
      if @user.update(user_params)
        format.html { redirect_to @user, notice: 'User was successfully updated.' }
      else
        format.html { render action: 'edit' }
      end
    end
  end

Upvotes: 2

Simmi Badhan
Simmi Badhan

Reputation: 533

Try adding a respond_to or redirect_to block in the update method to specify the path where user gets redirected to after a successful update.

Upvotes: 0

Related Questions