devise rails - error messages in different view? - ruby-on-rails-3

I'm trying to show my errors (both flash and devise) in one of my layout files (_header.html.erb):
<div id="alerts">
<% flash.each do |name, msg| %>
<%= content_tag :div, msg, :id => "flash_#{name}" if msg.is_a?(String) %>
<% end %>
<%= devise_error_messages! %>
</div>
but I'm getting an error: undefined local variable or method `resource', because the error message is no longer in the devise form. I tried the method suggested here: http://pupeno.com/2010/08/29/show-a-devise-log-in-form-in-another-page/ by pasting that code into the application_controller.rb file. No luck. Ideas?
oh. I forgot to mention... The pages work without error, but my tests are failing... Here's a failing test:
it 'succeeds with a valid email and password' do
user = Factory.create(:user)
visit sign_in_path
fill_in 'user_email', :with => user.email
fill_in 'user_password', :with => user.password
click_button 'Sign in'
page.should have_content("hi #{user.username}")
end
This is Rails3, fyi.

I was getting errors like this and solved using :partial and :locals when using the render method:
<%= render :partial => 'header', :locals => { :flash => flash } %>
See Rails 3: "undefined local variable or method" if I put content in a partial

turns out the code needed to be in the application_helper instead of the controller, but the code at pupeno.com works!

Related

authentication, cant go through login page

im trying create backend under password from database and i cant go through login page :P
My AdminController
class Backend::AdminController < ApplicationController
layout :layout
before_filter :authorize, :except => :login
def authorize
if session[:backend] != true
redirect_to backend_login_path
end
end
private
def layout
if session[:backend] == true
"admin"
else
"login"
end
end
def login
employee = Employee.authenticate(params[:name], params[:password])
if employee
session[:backend] = true
redirect_to backend_root_path, :notice => "Logged in!"
else
flash.now.alert = "Invalid login"
end
end
def logout
session[:backend] = nil
redirect_to backend_login_path, :notice => "Logged out!"
end
end
My Routes
match "backend/login" => "backend/admin#login"
match "backend/logout" => "backend/admin#logout"
My Login page
<% flash.each do |name, msg| %>
<%= content_tag :div, msg, :id => "flash_#{name}" %>
<% end %>
<h1>Log in</h1>
<%= form_tag backend_login_path do %>
<p>
<%= label_tag :name %><br />
<%= text_field_tag :name, params[:name] %>
</p>
<p>
<%= label_tag :password %><br />
<%= password_field_tag :password %>
</p>
<p class="button"><%= submit_tag "Log in" %></p>
<% end %>
when i go on url /backend im redirected to /backend/login, thats right
when i enter good login or bad login nothing happened and NO flashes appears thats strange ?
from webserver console output, i see the POST informations go through login method.. i dont know what is wrong ? thank you
edit: when i try go to URL /backend/logout im getting
Unknown action
The action 'logout' could not be found for Backend::AdminController
i really dont understand this :( im begginer
one of the conventions in rails is, that public methods in a controller are considered to be actions.
if you want to write methods for before_filter etc, make them private or protected so that rails will not expose them as actions.
on the flipside, you are not able to define actions as private.

Rails - how do I show an Add Favourite button to users who are not logged in?

I'd like to display an "Add to Favourites" button to users that are not logged in so that they can see that logged in users can add posts (in this case) to their favourites.
Here's the current code:
routes.rb
resources :users do
resources :favourites
end
resources :favourites, only: [:create, :destroy]
posts_helper.rb (I'll move this application_helper once I get it working)
PostsHelper
def new_favourite
if signed_in?
return current_user.favourites.build
else
return Favourite.new
end
end
end
show.html.erb
<%= render :partial => 'shared/favourites/favourite_form', :locals => { :object => #post } %>
_favourite_form.html.erb
<% if signed_in? && current_user.favourited?(object) %>
<%= render partial: 'shared/favourites/unfavourite', locals: { object: object } %>
<% else %>
<%= render partial: 'shared/favourites/favourite', locals: { object: object } %>
<% end %>
_favourite.html.erb
<%= form_for(new_favourite, remote: signed_in?) do |f| %>
<div>
<%= f.hidden_field :object_id, :value => object.id %>
<%= f.hidden_field :object_type, :value => object.class.name.demodulize %>
</div>
<%= button_tag(:type => 'submit', :id => 'add_favourite') do %>
Add to Favourites
<% end %>
<% end %>
I want it to not do an ajax call (ie submit the add favourite form using a page reload) if the user is not signed in so that it will see the user is trying to access a protected page, will redirect them to login and upon success [when it redirects them back to where they were originally trying to go] it will add the favourite.
Can someone advise what I would need to change to make this possible.
EDIT:
Code updated to reflect current state.
After signing in it redirects back to No route matches [GET] "/favourites" because favourites are a nested resource under users.
EDIT 2:
The redirect works pretty much the same as in Rails Tutorial:
Redirect user to sign in page (signed_in_user):
http://ruby.railstutorial.org/book/ruby-on-rails-tutorial#code-correct_user_before_filter
Store location to redirect user back to:
http://ruby.railstutorial.org/book/ruby-on-rails-tutorial#code-friendly_forwarding_code
http://ruby.railstutorial.org/book/ruby-on-rails-tutorial#code-friendly_session_create
The only difference is that on my signin page I use a facebook omniauth link for the user to login but the redirection after logging in still works as expected.
Use a helper method instead of current_user.favourites.build?
<%= form_for(new_favourite, remote: true) do |f| %>
Helper:
PostsHelper
def new_favourite
if signed_in?
return current_user.favourites.build
else
return Favourite.new
end
end
end

No route matches [POST] "/contacts/1"

app/view/contact/show.html/erb
<%= form_for(#contact) do |f| %>
<p id="notice"><%= notice %></p>
<p>
<b>Firstname:</b>
<%= #contact.firstname %>
</p>
<p>
<b>Lastname:</b>
<%= #contact.lastname %>
</p>
<p>
<b>Email:</b>
<%= #contact.email %>
</p>
<p>
<b>Mobilephone:</b>
<%= #contact.mobilephone %>
</p>
<% end %>
<%= link_to 'Edit', edit_contact_path(#contact) %> |
<%= link_to 'List', contacts_path %>
in my view/contact/index.html.erb i have a button
<%= button_to 'show', contact %>
in my contacts_controller.rb i just use automatic setting like:
def show
#contact = Contact.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #contact }
end
end
in my routes file
match '/contacts/:id/edit', :controller => 'contacts', :action => 'edit'
match '/contacts/contact_:id/show', :controller => 'contacts', :action => 'show'
resources :contacts
resources :connections
resources :addresses
root :to => 'contacts#index'
and after running rake routes i got
/contacts/:id/edit(.:format) contacts#edit
/contacts/:id/show(.:format) contacts#show
contacts GET /contacts(.:format) contacts#index
POST /contacts(.:format) contacts#create
new_contact GET /contacts/new(.:format) contacts#new
edit_contact GET /contacts/:id/edit(.:format) contacts#edit
contact GET /contacts/:id(.:format) contacts#show
PUT /contacts/:id(.:format) contacts#update
DELETE /contacts/:id(.:format) contacts#destroy
connections GET /connections(.:format) connections#index
POST /connections(.:format) connections#create
new_connection GET /connections/new(.:format) connections#new
edit_connection GET /connections/:id/edit(.:format) connections#edit
connection GET /connections/:id(.:format) connections#show
PUT /connections/:id(.:format) connections#update
DELETE /connections/:id(.:format) connections#destroy
addresses GET /addresses(.:format) addresses#index
POST /addresses(.:format) addresses#create
new_address GET /addresses/new(.:format) addresses#new
edit_address GET /addresses/:id/edit(.:format) addresses#edit
address GET /addresses/:id(.:format) addresses#show
PUT /addresses/:id(.:format) addresses#update
DELETE /addresses/:id(.:format) addresses#destroy
root / contacts#index
And when i click the button 'show' i got Routes Error No route matches [POST] "/contacts/1" Could somebody help me checking what mistake i have maken,please? Thank you very much for helping.
Maybe it's easier if you use the standard routing offered by resources contacts - then you could simply use <%= link_to 'show', contact_path(contact) %>
Also, the button should perform a GET request, not a POST since that route is not defined.
If I were you I would remove the first two custom routes you declared and just rely on the resources :contacts method instead. This in combination with a GET request should fix your problem.

Rails 3 Search Action Redirects To Show?

I've ran into a weird problem in Rails. When I try and submit a search query with the following form on my Uploads controller:
<%= form_tag ({:controller => "uploads", :action => 'find_uploads'}), :method => "get" do %>
<%=h text_field_tag :search, params[:search], :id => 'search_field' %>
<br />
<%= submit_tag "Search", :style=>"display:inline;" %>
<% end %>
I get redirected to the following url and error page:
/uploads/find_uploads?utf8=✓&search=bot&commit=Search
ActiveRecord::RecordNotFound in UploadsController#show
Couldn't find Upload with id=0
My find_uploads route: get 'uploads/find_uploads' => "uploads#find_uploads"
And when I did I rake routes this is what I got:
uploads_find_uploads GET /uploads/find_uploads(.:format) {:controller=>"uploads", :action=>"find_uploads"}
Everything seems to be in order... not sure why it's not working out as expected. For debugging purposes I dropped breakpoints in both my find_uploads and show actions and neither of them were reached so this error message must be lying to me as the UploadsController show action is never called!
This form is being rendered on my index page if it counts for anything.
I think it's taking find_uploads for an id.
Declare your routes like that:
resources :uploads do
collection do
get :find_uploads
end
end
ps: currently, when you do rake routes, /uploads/find_uploads is after /uploads/:id right?

Rendering the Devise edit Password Form

I'm trying to render the Devise edit password form within another view because I don't want to duplicate the edit pw logic.
I've tried the following (after generating the Devise views):
<%= render 'devise/passwords/edit' %>
<%= render 'devise/passwords/form' %>
And a number of other variations on render that all seem to give me the same error:
"ActionView::MissingTemplate in foo#foo
Missing partial devise/passwords/edit..."
This variation:
<%= render :file => 'devise/passwords/edit.html.erb' %>
Gave me some hope but the following error:
"undefined local variable or method `resource' for #<#:0x47ef0e0>"
around this line:
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f| %>
That makes me think I'm close (as that is code from the form that I want) but shouldn't that template be using the correct logic from the hidden Devise controller? Or do I need to do something in the routes file to get this to work?
Am I way off?
Try this:
<%= render :template => 'devise/passwords/edit',
:locals => {
:resource => my_user_model_variable,
:resource_name => my_user_model_name } %>
Where:
my_user_model_variable could be current_user
my_user_model_name could be "User"