rails 3 Admin Authentication - ruby-on-rails-3

Whats wrong in my authentication i also dont know..can someone tell me what wrong?
i got user scaffold, and this is my admin controller
class AdminController < ApplicationController
def login
if request.post?
user = User.authenticate(params[:name], params[:password])
if user
session[:user_id] = user.id
redirect_to(:action => "index")
else
flash.now[:notice] = "Invalid user/password combination"
end
end
end
def logout
session[:user_id] = nil
flash[:notice] = "Logged out"
redirect_to(:action => "login")
end
def index
end
end
and this is my admin/login.html.erb
<div>
<%= form_tag do %>
<fieldset>
<legend>Please Log In</legend>
<div>
<label for="name">Name:</label>
<%= text_field_tag :name, params[:name] %>
</div>
<div>
<label for="password">Password:</label>
<%= password_field_tag :password, params[:password] %>
</div>
<div>
<%= submit_tag "Login" %>
</div>
</fieldset>
<% end %>
</div>
but when i try to log in using existence user it come like this
No route matches "/admin/login"
whats wrong with my code??am i missing something?

You should do that
Hawary::Application.routes.draw do
post 'admin/login' => 'admin#login'
end

Related

Comments route in Rails 5.1

I am trying to create Comments on User created Articles in Rails 5.1.
After a Comment is submitted, the redirect should be to the '/articles/:id' but is instead redirecting to '/articles/:id/comments'.
I'm using nested routing in routes.rb:
devise_for :users
root to: "articles#index"
resources :articles do
resources :comments
end
My CommentsController.rb:
class CommentsController < ApplicationController
before_action :set_article
def create
unless current_user
flash[:alert] = "Please sign in or sign up first"
redirect_to new_user_session_path
else
#comment = #article.comments.build(comment_params)
#comment.user = current_user
if #comment.save
flash[:notice] = "Comment has been created"
else
flash.now[:alert] = "Comment not created correctly"
end
redirect_to article_path(#article)
end
end
private
def comment_params
params.require(:comment).permit(:body)
end
def set_article
#article = Article.find(params[:id])
end
end
The form for Comments in articles/show.html.erb:
<!--Start of comments-->
<div class="col-md-12">
<%= form_for [#article, #comment],
:html => {class: "form-horizontal", role: "form"} do
|f| %>
<% if #comment.errors.any? %>
<div class="panel panel-danger col-md-offset-1">
<div class="panel-heading">
<h2 class="panel-title">
<%= pluralize(#comment.error.count, "error") %>
prohibited this comment from being saved:
</h2>
<div class="panel-body">
<ul>
<% #comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
</div>
</div>
<% end %>
<div class="form-group">
<div class="control-label col-md-2">
<%= f.label :body, 'New Comment' %>
</div>
<div class="col-md-10">
<%= f.text_area :body, rows: 10, class: "form-control", placeholder: "New Comment" %>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<%= f.submit "Add Comment", class: "btn btn-primary btn-lg pull-right" %>
</div>
</div>
<% end %>
</div>
How do I make this submit button save and redirect back to 'articles/:id'? Thanks in Advance.
The routes generated by in your router will look something like this:
/articles/:article_id/comments/:id
This means, when you need to load your article in the CommentsController, you should do something like this (as suggested by #Marlin):
def set_article
#article = Article.find(params[:article_id])
end
Otherwise, you run the risk of attaching the comment to the incorrect article if there happens to be an ID collision between the IDs in the comments and article table. Or you simply get a ActiveRecord::RecordNotFound error.
But I know, that this doesn't answer your question directly, ut I suspect that the issue is that you're loading the wrong record from the db somewhere because of the above mentioned.
Try updating your code, and write a test, to make sure that you can programmatically reproduce the error :)

capybara current path

I'm trying to make a simple login example test in capybara where you use the user email and password to login, and it redirects to root_url with a notice "logged in"
For some reason capybara reports that I am at login_path "/login" after I use click_on log in, but when I run it rails s I am at root_path "/" with my notice.
What have I missed in either capybara or my test app?
All relevant code should be below.
controllers/sessions_controller.rb
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to root_url, notice: "logged in"
else
redirect_to login_path, notice: "Email or password incorrect"
end
end
view/sessions/new.html.erb
<h1>Sessions Log In</h1>
<%= form_tag sessions_path do %>
<div class="field">
<%= label_tag :email %><br />
<%= text_field_tag :email, params[:email] %>
</div>
<div class="field">
<%= label_tag :password %><br />
<%= password_field_tag :password %>
</div>
<div class="actions"><%= submit_tag "log in" %> </div>
<% end %>
login_spec.rb
it "should let you login with correct password" do
user = Factory.build(:user)
visit login_path
fill_in "Email", :with => user.email
fill_in "Password", :with => user.password
click_on "log in"
current_path.should == root_path
page.should have_content("logged in")
end
routes.rb
...
get 'login', to: 'sessions#new', as: 'login'
...
Factories.rb
Factory.define :user do |f|
f.sequence(:email) {|n| "a#{}#a.a"}
f.password "a"
end
Can you verify that you are actually logged in?
Try placing page.should have_content("logged in") before asserting current_path.
And why are you only building a user instead of creating/saving it. I hope you realise Factory.build(:user) functions different than Factory(:user) and it doesn't actually save the user.

Rails form submitted multiple times but don't know why

I have a form as follows:
<%= form_for(:session, :url => sessions_path, :remote => true, :html => {:id => 'login_form'}) do |f| %>
<div class="formRow">
<%= f.label :email %><br>
<%= f.text_field :email, :value => (#email if #email) %>
</div>
<div class="formRow">
<%= f.label :password %><br>
<%= f.password_field :password %>
</div>
<div class="formRow small">
<%= link_to "I forgot my password",'#' %>
</div>
<div class="formRow">
<%= f.submit signin_button_text, :class => "button-big left" %>
</div>
<% end %>
It goes to this controller:
def create
#email = params[:session][:email]
user = User.authenticate(params[:session][:email],params[:session][:password])
respond_to do |format|
if user.nil?
#title = "Sign in"
flash.now[:error] = "Invalid email/password combination"
format.js {render :action => :new }
else
sign_in user
format.js {render :action => :create }
end
end
end
Here is the new.js file:
$('#login_form').replaceWith("<%=escape_javascript(render 'login_form')%>");
if($('.flash-block').length ==0) {
$('#login_form').before("<div class='flash-block error'><span><%=escape_javascript(flash[:error])%></span></div>");
}
For some reason if the form is submitted with errors it loops four times.
I don't understand why.
Is there something in the code that causes this to loop?
I am assuming that you are using jquery. This is usually happened when there is an incomplete call or there is some sort of error and you haven't refresh the page. Try something like this:
<script type="text/javascript">
$('#login_form').submit(function() {
$(this).unbind('submit').submit();
});
</script>
I was using Fancybox and was not opening it in an iframe. So I wound up loading the jquery libraries twice and thus when I submitted the form I had multiple submissions.
Once I opened Fancybox in an iframe it submitted only once.

RoR Difficulty accessing params in controller

I have an edit page with the following code, basically a dropdown and button that calls update.
<% form_tag('switch_car', :method => :put) do%>
<div class="field">
<label>Car Name:</label>
<%= select("params", ":id", #available_cars.collect {|v| [v.name, v.id]})%>
</div>
<div>
<%= submit_tag "Switch Car" %>
</div>
<% end %>
The server reads like the params is being set:
Parameters: {"utf8"=>"Γ£ô", "authenticity_token"=>"8vHXrnICaOKrGns6FfMUcd/dWo5kpNKpA8F5l5ozRkY=", "params"=>{":id"=>"9"}, "commit"=>"Switch Car"}
However, when I put the params into a session I get nothing. It seems to be always nil. Not sure what I am doing wrong? Here is code in the controller.
def update
if params[:id]
session[:car_info_id] = params[:id]
redirect_to entry_url
else
redirect_to switch_car_path
end
end
It always gets redirected to the switch_car_path so I am assuming params[:id] is always nil. When I put if params[:id] == nil it goes to the entry_url.
Thanks in advance.
you want params[:params][":id"]
Alternatively, you could put this in your view:<%= select("car_info", "id", #available_cars.collect {|v| [v.name, v.id]})%>
And then in your controller:if params[:car_info][:id]
While the other answer would work, this is probably what you'd want to be doing (using select_tag(:id) will automatically add an :id key/value to the params hash):
<% form_tag('switch_car', :method => :put) do %>
<div class="field">
<label>Car Name:</label>
<%= select_tag(:id, options_from_collection_for_select(#available_cars, "id", "name")) %>
</div>
<div>
<%= submit_tag "Switch Car" %>
</div>
<% end %>
Then you can easily access params[:id] in the controller.

fields_for not rendering association name (belongs_to relationship)

I'm trying to create the form to create an event. Events belong_to a creator (of class user), and the form includes fields_for the creator.
Largely the form is working - it renders everything else properly, and the create action processes it properly when the fields_for #event.creator section is commented out. The fields_for tag is rendering event[user] tags instead of event[creator], though, and i can't figure out why. Ideas? Here are the relevant excerpts.
(in views/events/new.html.erb)
<%= form_for #event do |form| %>
<%= render :partial => '/events/form', :object => form %>
<%= form.submit 'Go!' %>
<% end %>
(in events/_form.html.erb)
...
<% if !signed_in? %>
To create your event, please provide an email address and create a password. <br />
<%= form.fields_for #event.creator do |uf| %>
<div class="email_field">
<%= uf.label :email %>
<%= uf.text_field :email, :type => "email" %>
</div>
...
<% end %>
<% end %>
(controllers/events_controller.rb)
def new
#event = Event.new
if !signed_in?
#event.build_creator
end
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #event }
end
end
(models/event.rb)
belongs_to :creator, :class_name => "User"
accepts_nested_attributes_for :creator
Largely this works, but the form elements render as
<div class="email_field">
<label for="event_user_email">Email</label>
<input id="event_user_email" name="event[user][email]" size="30" type="email" />
</div>
<div class="password_field">
<label for="event_user_password">Password</label>
<input id="event_user_password" name="event[user][password]" size="30" type="password" />
</div>
...
the issue here is event_user and event[user] instead of event_creator and event[creator]; when i submit the form i get an error that event doesn't have a User field.
<%= form.fields_for :creator, #event.creator do |uf| %>