use devise sign_in view in layout - ruby-on-rails-4

I have 2 layout
applicattion.html.erb
login.html.erb
I use devise.
in application_controller.rb I write this code:
protect_from_forgery with: :exception
layout :another_by_method
private
def another_by_method
if user_signed_in?
"application"
else
"login"
end
end
by this code, if user don't login_in, login.html.erb show.
I want use devise sign_in form in login.html.erb, but because of this code all of the page are redirect_to login.html.
I use below code too,
<%= render partial: "devise/sessions/new"%>
but get this error:
ActionView::MissingTemplate in Devise::Sessions#new
any idea?!

You are trying to render a partial, but devise/sessions/new is not a partial.
Anyway, have you generated the views with rails generate devise:views? If so, you could do that:
= render file: 'devise/sessions/new'
Use file instead of partial, but you will need all the variables provided by Devise, as resource, resource_name, or devise_mapping.

Related

Rails 4 undefined method `any?' for nil:NilClass

I am running a chat application on my RoR app. I want to be able to render the user chat conversations from my layouts/application.html.erb to have the user chat conversations across all pages but the chat is only working when I run the index action method under my Users controller [class UsersController < ApplicationController]. When I have my chat on views/users/index.html.erb runs great. Just to make it available in all pages I created a render form under views/users called _chatlist.html.erb which has this line inside:
and rendered this form in my layouts/application.html.erb body as:
<%= render partial: 'users/chatlist' %>
When I do that I get this error: undefined method `any?' for nil:NilClass.
How can I solve this nil issue? Any help will be appreciated.
You are getting that error because #conversations is not initialized.
You have to write an method and call it in application_controller.rb if you want to make it available on all the pages. Your application_controller.rb should look like this.
class ApplicationController < ActionController::Base
before_filter :load_conversatios
def load_conversatios
# load you conversation here
#conversations = Conversation.all
end
end
And I think that is not a good approach to load all the conversations on all the pages. You have to make it available from ajax call.

How do I render a page for nested routes

To learn rails, I started to write my own (stripped down) version of reddit. Currently, I have my comments routes nested inside my post routes as such:
resources :posts do
resources :comments
end
For my comments controller, under index & create I have the following
def index
#post = Post.find(params[:post_id])
#comments = #post.comments
if params[:comment].nil?
#comment = Comment.new
#comment.post_id = #post.id
else
#comment = Comment.find([:comment])
end
end
def create
#comment = Comment.new(comment_params)
#comment.user_id = current_user.id
#comment.post_id = params[:post_id]
if #comment.save
#flash
redirect_to post_path(#comment.post)
else
#flash
render 'index'
end
end
Which works well, except the last part: render
I want my comments to display on the same page as the other comments (just like reddit), so I would prefer not use the www.example.com/post/4/comment/new path, and instead do it through the www.example.com/post/4/comments path.
I understand that I can do a redirect, however I want to keep the comment text, so the user can make corrections. Is there a way to properly do this with a render, as opposed to me putting the text in a session variable and doing a redirect? I understand this is an edge case, but am trying to use this as a learning opportunity.
You can pass the comment to the index partial - no?
<%= render "index", locals: {comment: #comment} %>
Or try a partial;
<%= render partial: "index", locals: {comment: #comment} %>

Getting same style in another page when click to login

I am having a login page for user generated by devise gem.where I removed the registerable from model for only login not for signup.I have also generated an admin which gives default login credentials for user in seed.rb file.I have done some css work in login page. next I have generated an employee page for further process for users.
Here my doubt is the styling part what I have done in login page is also coming in employee page. I dont want that so I wrote some condition in application.html.erb
<% unless user_signed_in? %>
<%= render 'layouts/heading' %>
<% end %>
The method is defined in application.controller.rb
def user_signed_in? %>
render :layouts => 'application'
end
I tried a lot by changing conditions but it is still displaying or showing errors.
You said that you're using "device gem", but since you're talking about authentication, I assume you mean "devise"?
The user_signed_in? method is a helper which should be provided automatically by devise, and you should be able to use it in your views. You shouldn't need to define it in the application controller.
You probably want to make sure you do "before_filter :authenticate_user!" in the relevant controller (you can use the ":only" option if you only want this to apply for certain methods).
It's difficult to give any more information because you haven't said what errors you are getting. I assume you're getting some kind of syntax error on the definition of the "user_signed_in?" method, since you have an invalid "%>"on the end of the line, which I guess you copied-and-pasted from an ERB file.

dots in rails URL

I'm trying to add a show page to my devise users but can't seem to get the id value passed properly, how do I create a link to the show page? For some reason rails is doing this to URL
/show.1
users controller:
def show
#user = User.find(params[:id])
end
user/show.html.erb
<h1><%= #user.username %></h1>
link to user profile also gives me issues id no method
<%= link_to #post.email, users_show_path(#user.id) %>
routes.rb
get "users/show"
get "pages/faq"
get "pages/about"
devise_for :users
resources :posts
You have defined the show route as:
get "users/show"
Notice that there is no dynamic segment in this route, like :id. That means your route is not expecting any value to be passed. BUT while linking to this route you passed #user.id
<%= link_to #post.email, users_show_path(#user.id) %>
which the route was not expecting. So, Rails assumed that you are passing the format (like .html, .json, etc.) which is why you see the url formed as users/show.1.
To fix this, I would suggest you to add a dynamic segment to your route to capture the id of a user correctly.
Change
get "users/show"
With
get "users/show/:id" => "users#show", as: :users_show
For a user with id = 1, when you click on the user profile link the url generated would be http://yourdomain/users/show/1

How do I make a method available inside a partial?

I'm a rails beginner learning rails 4 and I'm trying to learn by doing. I'm making a simple blog that I want some simple user authentication on. I'm trying to learn here, so I don't want to implement Devise, etc. I have a header partial that takes care of my site header and I'm trying to put a link to logout that only shows if a user is logged in. I have a simple session controller that has a new action for the signup form, a create action that sets the current user after matching the email and password and sets session[:user_id] = #current_user.id, and a destroy action that nils out the session. In my application controller I have a method like this
def logged_in?
!session[:user_id].nil?
end
In my _header.html.erb partial, I have
<% if logged_in? %>
(My link)
<% end %>
When I load the page it tells me it can't find the "logged_in?" method. Anyone know why? Thanks.
Methods on controllers are by default not exposed to the views (which your partial is part of).
2 solutions:
Create your logged_in? method as a helper method, for example in an AuthenticationHelper. Doing this you cannot access it from controllers, though.
Expose your controller method to the view using helper_method:
class ApplicationController < ActionController::Base
helper_method :logged_in?
def logged_in?
[...]
end
end
Couldn't you just use:
if #current_user