This community looks great. I'm new to rails so please bear with some confusion. I have an app that lets a new user signup. The user gets created along with a wallet object that obtains a foreign key that matches the users given primary key. When I click logout, I return to the intended page, but all of a sudden, I am being thrown an "invalid combination" error... I feel like ever since I introduced the current_user helper method, that it's been throwing something off. Here are pieces of my files
The session's controller
class SessionsController < ApplicationController
skip_before_action :require_login, only: [:new, :create]
def new
end
def create
#user = User.find_by_email(params[:email])
if #user && #user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to "/users/#{#user.id}"
else
flash[:errors] = ["Invalid Combination"]
redirect_to "/sessions/new"
end
end
def destroy
session.delete(:user_id)
redirect_to "/sessions/new"
end
end
The user's controller
class UsersController < ApplicationController
skip_before_action :require_login, only: [:new, :create]
before_action :require_correct_user, only: [:edit, :show, :update, :destroy]
def new
end
def show
#user = User.includes(:wallet).find_by_id(params[:id])
end
def edit
end
def create
#user = User.create user_params
#wallet = Wallet.new
#wallet.save
#user.wallet_id = #wallet.id
#wallet.user = #user
if #user.save && #wallet.save
session[:user_id] = #user.id
redirect_to "/users/#{#user.id}"
else
flash[:errors] = #user.errors.full_messages + #wallet.errors.full_messages
redirect_to "/sessions/new"
end
end
private
def require_correct_user
if current_user != User.find(params[:id])
redirect_to "/users/#{session[:user_id]}"
end
end
def user_params
params.require(:user).permit(:email, :motto, :bio, :first_name,
:last_name,
:password, :password_confirmation)
end
end
And finally, here's the view I am directing to for both new signups and existing users login (sessions#new). Please let me know where you see any potential hiccups! Thanks!
<nav>
<div class="nav-wrapper">
<a href="#" class="brand-logo center">
<%=image_tag("straightupLogoSiteHome.png")%></a>
<ul id="nav-mobile" class="left hide-on-med-and-down">
</ul>
<ul id="nav-mobile" class="right hide-on-med-and-down">
</ul>
<ul class="side-nav" id="mobile-demo">
</ul>
</div>
</nav>
<div class="container">
<br><br>
<div class="row">
<h3 class="center light">SIMPLE P2P BETTING</h3>
<br><br><br>
<div class="col s5 push-s7">
<H5 class="light">OR PLEASE... JOIN US</H5>
<form action="/users" method="post">
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
<div class="input-field col s12">
<input type="text" id="Email" name = "user[email]">
<label for="Email">EMAIL</label>
</div>
<div class="input-field col s12">
<input type="text" id="Motto" name = "user[motto]">
<label for="Motto">YOUR MOTTO (OPTIONAL)</label>
</div>
<div class="input-field col s12">
<input type="text" id="Bio" name = "user[bio]">
<label for="Bio">A BIO (OPTIONAL)</label>
</div>
<div class="input-field col s6">
<input type="text" id="First_Name" name = "user[first_name]">
<label for="First_Name">FIRST NAME</label>
</div>
<div class="input-field col s6">
<input type="text" id="Last_Name" name = "user[last_name]">
<label for="Last_Name">HOUSE NAME</label>
</div>
<div class="input-field col s6">
<input type="text" id="Password" name = "user[password]">
<label for="Password">PASSWORD</label>
</div>
<div class="input-field col s6">
<input type="text" id="Password_Confirmation" name = "user[password_confirmation]">
<label for="Password_Confirmation">AND AGAIN!</label>
</div>
<a class="waves-effect waves-light btn"><input type="submit" name="Join" value="JOIN US"></a>
</form>
</div>
<div class="col s4 pull-s4">
<H5 class="light">LOG BACK IN. sorry...</H5>
<form action="/sessions" method="post">
<input type="hidden" name="authenticity_token" value="<%=
form_authenticity_token %>">
<div class="input-field col s12">
<input type="text" id="Email" name = "user[email]">
<label for="Email">EMAIL</label>
</div>
<div class="input-field col s12">
<input type="text" id="Password" name = "user[password]">
<label for="Password">PASSWORD</label>
</div>
<a class="waves-effect waves-light btn"><input type="submit" name="login" value="Login"></a>
</form>
</div>
</div>
</div>
Aplogies. The current_user is defined in the applications_controller below. Thanks!
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
def authorize
redirect_to "/sessions/new" unless current_user
end
end
Ok. The issue was here... The answer I received was a bit of a workaround which is not at all what I need when I'm learning. So in my sessions_controller, I was defining a user by the params specified for the user in the users_controller. What I needed to do was define say login_params within the sessions_controller.. either that or in the create method .find_by_email(params[user.email]). I chose to create this private method at the bottom and changed the
.find_by_email(params[:email]) and the authenticate(params[:password])
to
.find_by_email(login_params[:email]) and the authenticate(login_params[:password])
private
def login_params
params.require(:user).permit(:email, :password)
end
Related
I am trying to update user info and i am having error that it didn't get any data from my form
Here is my user.controller:
def update
if !session[:id]
redirect_to '/users'
else
#user = User.find(params[:id])
#user.update(update_params)
if #user.valid?
#user.save
redirect_to '/events'
else
flash[:errors] = #user.errors.full_messages
redirect_to "/users/#{#user.id}/edit"
end
end
end
def update_params
params.require(:user).permit(:fname, :lname, :email, :city, :state)
end
edit update form
here is my edit.html.erb form:
<form action="/users/<%= #user.id %>/update" method="post">
<input type="hidden" name="_method" value="patch">
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
<div class="form-group row">
<label for="fname" class="col-sm-2 col-form-label">First Name</label>
<div class="col-sm-10">
<input type="text" name="user[fname]" class="form-control" placeholder="<%= #user.fname %>">
</div>
</div>
<div class="form-group row">
<label for="lname" class="col-sm-2 col-form-label">Last Name</label>
<div class="col-sm-10">
<input type="text" name="user[lname]" class="form-control" placeholder="<%= #user.lname %>">
</div>
</div>
<div class="form-group row">
<label for="email" class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10">
<input type="email" name="user[email]" class="form-control" placeholder="<%= #user.email %>">
</div>
</div>
<div class="form-group row">
<label for="location" class="col-sm-2 col-form-label">Location</label>
<div class="col-sm-5">
<input type="text" name="user[city]" class="form-control" placeholder="<%= #user.city %>">
</div>
<div class="col-sm-5">
<select class="custom-select" name="user[state]">
<%= options_for_select(us_states)%>
</select>
</div>
</div>
<div class="form-group row clearfix">
<div class="col-sm-10 offset-sm-2">
<button type="submit" class="btn btn-primary float-right">Update</button>
</div>
</div>
</form>
Just updated my html form
this is error in terminal when i hit submit from my form:
(0.1ms) begin transaction User Exists (1.7ms) SELECT 1 AS one
FROM "users" WHERE ("users"."email" = 'nhan13574#gmail.com' AND
"users"."id" != 1) LIMIT 1 (0.1ms) rollback transaction Redirected
to http://localhost:4000/users/1/edit
Can you share the form? mostly the issue is there.
Also, #user.update actually saves the data in db, no need to save after it.. here is a refactored version of your snippet:
def update
return redirect_to '/users' unless session[:id]
#user = User.find(params[:id])
if #user.update(update_params)
redirect_to '/events'
else
flash[:errors] = #user.errors.full_messages
redirect_to "/users/#{#user.id}/edit"
end
end
I have built a sign up page in ruby on rails. I want to validate this sign up form. For example - if user left any section blank, the form will show an error message. It will also check whether the given email is unique. How can I do this by not changing my form?
#This my logins_controller.rb file
class LoginsController < ApplicationController
skip_before_action :verify_authenticity_token
def index
#subscriber=Subscriber.new()
end
def sign_up
subscriberNew = Subscriber.new
subscriberNew.name = params[:name]
subscriberNew.cus_user_name = params[:user_name]
subscriberNew.cus_password = params[:password]
subscriberNew.cus_email = params[:email]
result = subscriberNew.save
respond_to do |format|
msg = { :status => "ok", :message => "Success!" }
format.json { render :json => msg }
end
end
def validate_signup
#what should i write here?
end
end
and this is my sign up form
<div class="container">
<div class="shadow-lg p-3 mb-5 bg-white rounded view-card">
<h4 class="card-title">
<a href="/product_types">
<i class="material-icons">
arrow_back_ios
</i></a></h4>
<form id="signup_form" method="post" action="/sign-up">
<p class="h4 mb-4">Register to Binimoy</p>
<label for="name">Name</label>
<input type="text" name="name" id="name" class="form-control mb-4" placeholder="Name">
<label for="email">Email</label>
<input type="email" name="email" id="email" class="form-control mb-4" placeholder="Email">
<label for="phone">Phone</label>
<input type="text" name="phone" id="phone" class="form-control mb-4" placeholder="Phone">
<label for="name">Password</label>
<input type="password" name="password" id="password" class="form-control mb-4" placeholder="Password">
<div class="form-row mb-4">
<div class="col">
<button class="btn btn-default my-4 btn-block" type="reset">Reset</button>
</div>
<div class="col">
<button type="button" class="btn btn-info my-4 btn-block" id="submitAnchor">Submit</button>
</div>
</div>
</form>
</div>
First, use Rails helpers in your views and write your form as documented here.
<%= form_with url: sign_up_path do |form| %>
<%= form.label :email %>
<%= form.text_field :email %>
...
<%= form.submit %>
<% end %>
Second, use validations in your Subscriber model as documented here.
validates :email, presence: true, uniqueness: true
...
Hope it helps ;)
Rails is an framework with an strong opinion how to do things. You are doing things not the Rails way and this will make it more complicated.
If you really do not want to change your form (which is strongly advice against)
Add validations, check the return value of save and send back some error message
In your model:
validates :email, presence: true, uniqueness: true
In your controller:
if subscriber.save
render json: {status: "ok", message: "success"}
else
render json: {status: "nok", message: "something went wrong"}
end
Probably you should get rid of the status property and use the HTTP status code for this (sending back 201 (created) and 422 (unprocessble entity) responses instead)
Some other recommendatations to make your code more readable:
Follow the Rails conventions (use a form builder, it simplifies the assignment of form params to the model
Use Ruby naming conventions:
subscriberNew
should be
subscriber_new
since Ruby uses camel_case
but actually there is no need for the new suffix, so subscriber is enough
Use two spaces for identation
Don't abbreviate variables (cus_username, ...) and don't prefix when there is no need
I'm working on a rails api and using devise_token_auth for the authentication, when I try to update password by hitting the /auth/password with put request it responsds with error 401 i.e. unauthorized. My server logs show me this
Started PUT "/auth/password" Processing by
DeviseTokenAuth::PasswordsController#update as HTML Parameters:
{"password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}
Can't verify CSRF token authenticity Completed 401 Unauthorized in
routes.rb
mount_devise_token_auth_for 'User', at: 'auth' ,:controllers => { :omniauth_callbacks => 'omniauth' }
view.html (angularjs)
<div class="container">
<div class="row">
<div class="row">
<div class="col-xs-6 col-xs-offset-3 que">
<img src="./uploads/img/web-logo.png" class="img-responsive" alt="Logo">
</div>
</div>
<div class="col-xs-12 reset-pas">
<form name="update_pass" ng-submit="updatePassword_controller()" role="form" class="lost_reset_password">
<p class="error_msg" ng-show="update_pass.password_confirmation.$error.passwordVerify">
Passwords are not equal!
</p>
<label>New password</label>
<input type="password" name="password" ng-minlength="8" ng-model="updatePasswordForm.password" required="required" class="form-control">
<span>Minimum 8 Charachters</span>
<br>
<label>Re-enter new password</label>
<input type="password" name="password_confirmation" ng-minlength="8" ng-model="updatePasswordForm.password_confirmation" required="required" class="form-control" password-verify="updatePasswordForm.password" >
<button type="submit" class="btn btn-default" id="reset-submit">Save</button>
</form>
</div>
</div>
</div>
controller.js
$scope.updatePassword_controller = function() {
$auth.updatePassword($scope.updatePasswordForm)
.then(function(resp) {
console.log(resp)
$location.path('/')
})
.catch(function(resp) {
console.log(resp)
});
};
Update
Note
I'm facing this issue only for password update
Update
I installed gem 'angular_rails_csrf' Now it's giving only the authorization error not the csrf attack error
Use the Rails form_tag or form_for helpers. They add will add a hidden field for the XCSRF token:
<div class="container">
<div class="row">
<div class="row">
<div class="col-xs-6 col-xs-offset-3 que">
<img src="./uploads/img/web-logo.png" class="img-responsive" alt="Logo">
</div>
</div>
<div class="col-xs-12 reset-pas">
<%= form_tag "#", { "ng-submit" => "updatePassword_controller()", "role" => "form", "class" => "lost_reset_password"} do %>
<p class="error_msg" ng-show="update_pass.password_confirmation.$error.passwordVerify">
Passwords are not equal!
</p>
<label>New password</label>
<input type="password" name="password" ng-minlength="8" ng-model="updatePasswordForm.password" required="required" class="form-control">
<span>Minimum 8 Charachters</span>
<br>
<label>Re-enter new password</label>
<input type="password" name="password_confirmation" ng-minlength="8" ng-model="updatePasswordForm.password_confirmation" required="required" class="form-control" password-verify="updatePasswordForm.password" >
<button type="submit" class="btn btn-default" id="reset-submit">Save</button>
</form>
</div>
</div>
</div>
I simply made a condition in applicationcontroller.rb like below and it worked out . The main idea is simply to override the functionality of Devise
if params[:controller] == "devise_token_auth/passwords" && params[:action] == "update"
uri = URI.parse(request.headers.env['HTTP_REFERER'])
query_params = CGI.parse(uri.query)
email = query_params['uid'].first
user = User.find_by_email(email)
user.password = params[:password]
user.password_confirmation = params[:password_confirmation]
if user.save
render json: {message: 'Password Updated successfully', status: 200}
else
render json: {message: 'Password Could not changed , Please contact to support Team', status: 401}
end
end
Although it's not the proper solution but i couldn't think of anyother one . So please bear with me .In it we're fetching email from url
I'm working on a simple one-page website on Ruby on Rails that has a 'Contact Us' form. It has 3 fields - name, e-mail and text -, and a submit button. In theory, after filling up these forms and clicking the button, the user will receive an email with the confirmation of the request. The controller basically has only one method that writes the data in the DB and after successful saving sends an email.
The problem is that the controller doesn't receive the parameters(name, email and text) and raises an exception: ActionController::ParameterMissing (param is missing or the value is empty: application)
I'm sure that the data is sent. Here's the log:
Started POST "/" for 127.0.0.1 at 2015-07-23 20:25:08 +0300
Processing by ApplicationsController#create as HTML
Parameters: {"name"=>"Foo Bar", "email"=>"foobar#example.com", "text"=>"qwerqwepoiqtwporihtqwojbr[sdfzxc"}
Completed 400 Bad Request in 381609ms
Source code of the controller:
class ApplicationsController < ApplicationController
skip_before_filter :verify_authenticity_token, :if => Proc.new { |c| c.request.format == 'text/html' }
def new
#request = Application.new
end
def create
#request = Application.new(application_params)
if #request.save
ApplicationMailer.request_confirmation(#request).deliver_now
flash[:info] = 'Your application has been registered! Check your e-mail!'
else
flash[:alert] = 'Oops! Your application was not registered!'
end
end
private
def application_params
params.require(:application).permit(:name, :email, :text)
end
end
Source code of the Application model:
class Application < ActiveRecord::Base
before_save{
self.email.downcase!
}
validates(:name, presence: true, length: { maximum: 50 })
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
validates(:email, presence: true, length: {maximum: 255},
format: {with: VALID_EMAIL_REGEX})
validates(:text, presence: true)
end
Does anybody have any idea where is the problem and how to solve it?
Thank you in advance.
UPD:
Form code:
<form method="post" class="form-horizontal col-md-8" name="application" id="applyForm">
<div class="row" id="credentials">
<div class="col-sm-6">
<div class="input-group form-group" id="full_name">
<span class="input-group-addon" id="basic-addon1"><i class="fa fa-user"></i></span>
<input type="text" name="name" class="form-control" placeholder="Your name" aria-describedby="basic-addon1" id="name">
</div>
</div>
<div class="col-sm-6">
<div class="input-group form-group" id="email">
<span class="input-group-addon" id="basic-addon1"><i class="fa fa-envelope"></i></span>
<input type="text" name="email" class="form-control" placeholder="E-mail" aria-describedby="basic-addon1" id="email">
</div>
</div>
</div>
<div class="row" id="comment-area">
<div class="col-sm-12" id="comment">
<textarea class="form-control" name="text" rows="10" placeholder="Please describe your system" id="text"></textarea>
</div>
</div>
<div class="row" id="submit-button">
<button type="submit" class="btn btn-default"><i class="fa fa-rocket"></i>Send message</button>
</div>
</form>
Your params are not coming from application, for a quick fix just change application_params to below
def application_params
params.permit(:name, :email, :text)
end
So I got stripe up and running, however I have 3 different payment plans.
I'd like to capture what plan they clicked on, and use that to connect them to their right plan id.
This is what my form looks like:
<%= form_tag charges_path, id: "payment-form" do %>
<span class="payment-errors"></span>
<div class="form-row">
<label>
<span>Card Number</span>
<input type="text" size="20" data-stripe="number" maxlength="20" />
</label>
</div>
<div class="form-row">
<label>
<span>CVC</span>
<input type="text" size="4" data-stripe="cvc" maxlength="4"/>
</label>
</div>
<div class="form-row">
<label>
<span>Expiration (MM/YYYY)</span>
<input type="text" size="2" data-stripe="exp-month" maxlength="2"/>
</label>
<span> / </span>
<input type="text" size="4" data-stripe="exp-year" maxlength="4"/>
</div>
<button type="submit">Submit Payment</button>
<% end %>
I link to them like this:
<%= link_to 'Start Your Free Trial', new_charge_path(:plan_id => 1) %>
and the controller looks like this:
def create
customer = Stripe::Customer.create(
:email => 'exaimple#stripe.com',
:plan => plan_id,
:card => params[:stripeToken]
)
current_user.update_attributes(:stripe_customer_token => customer.id)
redirect_to root_url, notice: 'Successfully subscribed'
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to charges_path
end
which results in the error:
undefined local variable or method `plan_id'