Home > front end >  Rails 7 with devise how to yield login page
Rails 7 with devise how to yield login page

Time:11-14

I would like to display my login partial on the landing page. I have constructed a 2 layout site in Rails 7, views/layouts/application.html.erb and views/layouts/landing.html.erb. Each contains a yield.

When not logged in I go to the landing page correctly.

My current problem is that the devise views/devise/sessions/new.html.erb does not render when i click the sign in button. I added skip_before_action :authenticate_user! in my StaticPagesController to ensure that devise accepts that this is viewable without being logged in. If I remove the skip_before_action :authenticate_user! in my StaticPagesController it renders views/devise/sessions/new.html.erb every time and not the landing page text welcome text which is placed in views/static_pages/landing.html.erb

My server logs with skip_before_action :authenticate_user! in StaticPagesController and button click:

hellorails-web-1       | Started POST "/users" for 172.22.0.1 at 2022-11-10 09:23:44  0000
hellorails-web-1       | Processing by Devise::RegistrationsController#create as TURBO_STREAM
hellorails-web-1       |   Parameters: {"authenticity_token"=>"[FILTERED]"}
hellorails-web-1       |   Rendering layout layouts/landing.html.erb
hellorails-web-1       |   Rendering devise/registrations/new.html.erb within layouts/landing
hellorails-web-1       |   Rendered devise/shared/_error_messages.html.erb (Duration: 1.9ms | Allocations: 942)
hellorails-web-1       |   Rendered devise/shared/_links.html.erb (Duration: 0.3ms | Allocations: 136)
hellorails-web-1       |   Rendered devise/registrations/new.html.erb within layouts/landing (Duration: 6.6ms | Allocations: 3479)

It tries to render the correct data in the correct layout but it does not reflect that in my browser.

My server logs with skip_before_action :authenticate_user! in StaticPagesController removed. As expected does 401 and then renders the log in page in my template.

hellorails-web-1       | Started GET "/" for 172.22.0.1 at 2022-11-10 09:31:27  0000
hellorails-web-1       | Processing by StaticPagesController#landing as HTML
hellorails-web-1       | Completed 401 Unauthorized in 2ms (Allocations: 1041)
hellorails-web-1       | 
hellorails-web-1       | 
hellorails-web-1       | Started GET "/users/sign_in" for 172.22.0.1 at 2022-11-10 09:31:27  0000
hellorails-web-1       | Processing by Devise::SessionsController#new as HTML
hellorails-web-1       |   Rendering layout layouts/landing.html.erb
hellorails-web-1       |   Rendering devise/sessions/new.html.erb within layouts/landing
hellorails-web-1       |   Rendered devise/shared/_links.html.erb (Duration: 0.3ms | Allocations: 210)
hellorails-web-1       |   Rendered devise/sessions/new.html.erb within layouts/landing (Duration: 2.5ms | Allocations: 1538)
hellorails-web-1       |   Rendered layout layouts/landing.html.erb (Duration: 11.3ms | Allocations: 3945)
hellorails-web-1       | Completed 200 OK in 48ms (Views: 12.6ms | ActiveRecord: 12.2ms | Allocations: 17279)

It may be an turbo stream issue as that is the only difference i see in response type but i can't seem to find a solution to this.

Here is my setup:

My static pages controller:

class StaticPagesController < ApplicationController
  skip_before_action :authenticate_user! #If this is removed devise login page is rendered every time
  def landing
    layout "landing"
  end
end

My application controller:

class ApplicationController < ActionController::Base
  before_action :authenticate_user!
  layout :layout_by_resource

  private

  def layout_by_resource
    if devise_controller? #Add later: skip landing if logged in. 
      "landing"
    else
      "application"
    end
  end
end

My routes:

Rails.application.routes.draw do
  get 'static_pages/landing'

  devise_for :users

  root 'static_pages#landing'
end

Stripped landing.html.erb layout:

<!DOCTYPE html>
<html >
<head>
  <title>Landing</title>
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <%= csrf_meta_tags %>
  <%= csp_meta_tag %>
  <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
  <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>

  <link href="https://fonts.googleapis.com/css?family=Source Sans Pro:400,700" rel="stylesheet">

  
</head>

<body  style="font-family: 'Source Sans Pro', sans-serif;">
<div  style="background-image:url(<%=asset_path('bg.svg')%>);">

<% if user_signed_in? %>
  <%= button_to("Sign out",
                user_registration_path,
                class:"bg-blue-500 hover:bg-indigo-800 text-white font-bold py-2 px-4 rounded",
                ) %>
<% else %>
  <%= button_to("Sign in", user_registration_path, class:"bg-blue-500 hover:bg-indigo-800 text-white font-bold py-2 px-4 rounded") %>
<% end %>
  </div>
<%= yield %>
</body>
</html>

added to device config for turbo streams:

config.navigational_formats = ['*/*', :html, :turbo_stream]

Thanks in advance

CodePudding user response:

One option is to disable turbo for the button_to like:

 <%= button_to("Sign in", user_registration_path, data: { turbo: false }, class:"bg-blue-500 hover:bg-indigo-800 text-white font-bold py-2 px-4 rounded") %>

  • Related