1

I've installed devise for my rails app, i can go to the sign in page or the sign up page. But I want them both on a welcome page...

So I've made a welcome_page_controller.rb with the following function:

    class WelcomePageController < ApplicationController
  def index
    render :template => '/devise/sessions/new'
    render :template => '/devise/registration/new'

  end
end

But when i go to the welcome page i get this error:

NameError in Welcome_page#index

Showing /Users/tboeree/Dropbox/rails_projects/rebasev4/app/views/devise/sessions/new.html.erb where line #5 raised:

undefined local variable or method `resource' for #<#<Class:0x104931c>:0x102749c>
Extracted source (around line #5):

2: <% @header_title = "Login" %>
3: 
4: 
5: <%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
6:   <p><%= f.label :email %><br />
7:   <%= f.email_field :email %></p>
8: 

Does anybody knows a solution for this problem? Thanks in advance!

Does it have to do with the fact that it is missing the resource function? in the welcome_page controller? It's probably somewhere in the devise controller...?

Regards, Thijs

Thijs
  • 387
  • 5
  • 20

1 Answers1

5

Here's how I managed to did it.

I've put a sign up form in my home#index

My files:

view/home/index.html.erb

<%= render :file => 'registrations/new' %>

helper/home_helper.rb

module HomeHelper
  def resource_name
    :user
  end

  def resource
    @resource = session[:subscription] || User.new
  end

  def devise_mapping
    @devise_mapping ||= Devise.mappings[:user]
  end

  def devise_error_messages!
    return "" if resource.errors.empty?

    messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
    sentence = I18n.t("errors.messages.not_saved",
                      :count => resource.errors.count,
                      :resource => resource_name)

    html = <<-HTML
<div id="error_explanation">
<h2>#{sentence}</h2>
<ul>#{messages}</ul>
</div>
HTML

    html.html_safe
  end

end

You need that part because Devise works with something called resource and it should be defined so you can call your registration#new anywhere.

Like that, you should be able to register. However, I needed to display errors on the same page. Here's what I added:

layout/home.html.erb (the layout used by index view)

<% flash.each do |name, msg| %>

  # New code (allow for flash elements to be arrays)
  <% if msg.class == Array %>
    <% msg.each do |message| %>
      <%= content_tag :div, message, :id => "flash_#{name}" %>
    <% end %>
  <% else %>

    # old code
    <%= content_tag :div, msg, :id => "flash_#{name}" %>

  <% end %> #don't forget the extra end
<% end %>

I found this code here

And here's something I created: I saved my resource object if invalid in a session so that the user hasn't to fill every field again. I guess a better solution exists but it works and it's enough for me ;)

controller/registration_controller.rb

def create
    build_resource

    if resource.save
      if resource.active_for_authentication?
        # We delete the session created by an incomplete subscription if it exists.
        if !session[:subscription].nil?
          session[:subscription] = nil
        end

        set_flash_message :notice, :signed_up if is_navigational_format?
        sign_in(resource_name, resource)
        respond_with resource, :location => redirect_location(resource_name, resource)
      else
        set_flash_message :notice, :inactive_signed_up, :reason => resource.inactive_message.to_s if is_navigational_format?
        expire_session_data_after_sign_in!
        respond_with resource, :location => after_inactive_sign_up_path_for(resource)
      end
    else
      clean_up_passwords(resource)
      # Solution for displaying Devise errors on the homepage found on:
      # https://stackoverflow.com/questions/4101641/rails-devise-handling-devise-error-messages
      flash[:notice] = flash[:notice].to_a.concat resource.errors.full_messages
      # We store the invalid object in session so the user hasn't to fill every fields again.
      # The session is deleted if the subscription becomes valid.
      session[:subscription] = resource
      redirect_to root_path #Set the path you want here
    end
  end

I think I didn't forget any code. Feel free to use whatever you need.

Also, you can add your sign in form in the same page (something like that:)

<%= form_for("user", :url => user_session_path) do |f| %>  
  <%= f.text_field :email %>      
  <%= f.password_field :password %>
  <%= f.submit 'Sign in' %>
  <%= f.check_box :remember_me %>
  <%= f.label :remember_me %>
  <%= link_to "Forgot your password?", new_password_path('user') %>
<% end %>

Cheers !

Community
  • 1
  • 1
Lucas
  • 2,886
  • 1
  • 27
  • 40
  • Wow thank you very much!! I will try soon! can you tell why you used this code: html = <<-HTML in your script? Thanks again, best regards, Thijs – Thijs Jul 01 '11 at 15:53
  • That's actually code provided by Devise Helper itself. You can find the code [here](https://github.com/plataformatec/devise/blob/30f9da9d71640025f78f46f359e371fcd02add66/app/helpers/devise_helper.rb) – Lucas Jul 01 '11 at 16:08
  • i've tried it and it works... only i lost my css? i work with rails 3.1rc4 and if i copy/paste the devise.css.scss to welcome_page.css.scss it doesn't work? And when i enter not valid data it will go to /users/registration... but maybe that has to do with my routing, i have to redirect home to the welcom page, i think? Best regards, – Thijs Jul 01 '11 at 16:11
  • Uh? The code I posted has nothing to do with CSS, so maybe check your basics (HTML/CSS) ? You have to change that line `redirect_to root_path #Set the path you want here` to choose the redirect path when errors happen. – Lucas Jul 01 '11 at 16:44
  • Yes you're right offcourse... i had a layout direction in the application_controller.rb and that pointed to the wrong layout! I'll change the redirect to links and then it should work! Thanks again! Regards, Thijs – Thijs Jul 01 '11 at 18:42