Reputation: 2470
Am new to ruby on rails. Here am trying to post html form to ruby on rails (5.2.3 versions) To this effect, I reference solution found here link
<form accept-charset="UTF-8" method='post' action='http://localhost:3000/user1s'>
<label for='name'>Name</label>
<input type="text" name='name' placeholder='Enter your name'> <br>
<label for='password'>password</label>
<input type="text" name='password' placeholder='Enter your password'> <br>
<label for='email'>confirm pass</label>
<input type="text" name='password_confirmation' placeholder='Enter your password_confirmation'> <br>
<input type="submit" value='Save'>
</form>
user1 controller
class User1sController < ApplicationController
# POST /user1s
# POST /user1s.json
def create
@name = params[:name]
@password = params[:password]
@password_confirmation = params[:password_confirmation]
@user1 = User1.new(name=>@name, password=>@password , password_confirmation=>@password_confirmation)
respond_to do |format|
if @user1.save
format.html { redirect_to @user1, notice: 'User1 was successfully created.' }
format.json { render :show, status: :created, location: @user1 }
#format.json {status: :created }
else
format.html { render :new }
format.json { render json: @user1.errors, status: :unprocessable_entity }
end
end
end
end
Here is config/routes.rb
Rails.application.routes.draw do
#resources :user1s
post '/user1s', to: 'user1s#create', as: 'user1s'
end
When I run the code am getting the following error
The browser returned a 'null' origin for a request with origin-based forgery protection turned on. This usually means you have the 'no-referrer' Referrer-Policy header enabled, or that the request came from a site that refused to give its origin. This makes it impossible for Rails to verify the source of the requests. Likely the best solution is to change your referrer policy to something less strict like same-origin or strict-same-origin. If you cannot change the referrer policy, you can disable origin checking with the Rails.application.config.action_controller.forgery_protection_origin_check setting.
To mitigate the error above, I referenced link here which suggests solutions below yet cannot get it to work. link 2
at config/application.rb i have
Bundler.require(*Rails.groups)
module Saverecord
class Application < Rails::Application
Rails.application.config.action_controller.forgery_protection_origin_check = false
config.action_controller.allow_forgery_protection = false
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2
end
end
at application controller I have
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
protect_from_forgery with: :null_session
end
Upvotes: 4
Views: 4108
Reputation: 101891
This is much easier if you just follow the rails conventions.
Start by using strong parameters instead of copying variables twice from the params hash.
class User1sController < ApplicationController
# POST /user1s
# POST /user1s.json
def create
# Use strong parameters instead
@user1 = User1.new(user1_parameters)
respond_to do |format|
if @user1.save
format.html { redirect_to @user1, notice: 'User1 was successfully created.' }
format.json { render :show, status: :created, location: @user1 }
#format.json {status: :created }
else
format.html { render :new }
format.json { render json: @user1.errors, status: :unprocessable_entity }
end
end
end
# ...
private
def user1_parameters
params.require(:user1).permit(:name, :email, :password, :password_confirmation)
end
end
Ruby (and Rails) have fantastic features for manipulating hashes. If you are ever copying keys manually from one hash to another you are doing it wrong.
Then use the form helper instead of manually creating a form:
<%= form_with(model: @user1) do |form| %>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name %>
</div>
<div class="field">
<%= form.label :email %>
<%= form.email_field :email %>
</div>
<div class="field">
<%= form.label :password %>
<%= form.password_field :password %>
</div>
<div class="field">
<%= form.label :password_confirmation %>
<%= form.password_field :password_confirmation %>
</div>
<div class="actions">
<% form.submit %>
</div>
<% end %>
Rails has built in Cross Site Reference Forgery (CSRF) countermeasures which means that Rails will reject form submission that do not contain a valid CSRF token. When you create a form with form_with
(or the older form_tag
and form_for
) Rails includes a CSRF token as a hidden input in the form.
That means your hand-crafted form is a no go unless you disable the CSRF protection or provide the token which is much more complicated then just using the form helpers.
Your form also does not use the correct name
attributes for a nested hash. Rails by convention uses nested hashes:
{
users1: {
name: 'foo',
email: '[email protected]'
...
}
}
The form helper do this by setting the correct name attribute on the inputs:
<input type="email" name='user1[email]' ...>
Which works with params.require(:user1).permit(...)
. Your form will give an ActionController::ParameterMissing
error. You can work around this to use flat hashes but you might as well learn the Rails Way which avoids potential name collisions.
Upvotes: 5