I have signup form on my home screen. If user inputs invalid data I redirect him to /signin page. On this page I can see filled fields, but errors descriptions are empty.
Here is my UsersController:
class UsersController < ApplicationController
def new
#user = User.new(params[:user])
end
def create
#user = User.new(params[:user])
print #user
if #user.save
else
render 'new'
end
end
end
Method I use to show errors
module ApplicationHelper
def errors_for(model, attribute)
if model.errors[attribute].present?
content_tag :div, :class => 'well error' do
content_tag :ul do
model.errors[attribute].collect {|item| concat(content_tag(:li, item))}
end
end
end
end
end
My form partial:
<%= f.label :user_name %>
<%= f.text_field :user_name, :class=>"input-medium" %>
<%= errors_for(#user, :user_name) %>
<%= f.label :email %>
<%= f.text_field :email, :class=>"input-medium " %>
<%= errors_for(#user, :email) %>
<%= f.label :password %>
<%= f.password_field :password, :class=>"input-medium" %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, :class=>"input-medium" %>
and my signup view:
<section class="centered user-form-container">
<div class="user-form well pull-left">
<div class="centered">
<h1>Sign up</h1>
<%= form_for(#user, :action=>"create") do |f| %>
<%= render 'signup', :f=>f %>
<%= f.submit "Sign up" %>
<% end %>
</div>
</div>
</section>
In this situation, I believe you need to use flash.now, something like this:
Per the rails docs:
By default, adding values to the flash will make them available to the next request, but sometimes you may want to access those values in the same request. For example, if the create action fails to save a resource and you render the new template directly, that’s not going to result in a new request, but you may still want to display a message using the flash. To do this, you can use flash.now in the same way you use the normal flash:
def create
#user = User.new(params[:user])
print #user
if #user.save
else
# start with this, then expand the error text
flash.now[:error] = "Could not save user"
render 'new'
end
end
You would do this in your validation method.
If you are using a standard rails validation you would do this:
validates_presence_of :foo, :message => 'Message you want to display here'
If you are doing a custom validation then this:
def my_validation_method
begin
my_validation_code_here
rescue
self.errors[:base] << 'Message you want to display here'
end
end
def new
#user = User.new(params[:user])
if (!params[:user].nil?)
#user.valid?
end
end
Related
How can I make an error notice when somebody leaves spaces empty, etc...
I tried enumerous codes and they either didn't work or failed... I even installed a gem but nothing worked until now... please help with ideas/solutions
<div class="jumbotron"
<div class="container">
<h2>Signup</h2>
<%= form_for :user, url: '/users' do |f| %>
Número de Empregado: <br>
<%= f.number_field :NumeroEmpregado %><br>
Primeiro e Último Nome: <br>
<%= f.text_field :nome %><br>
Password: <br>
<%= f.password_field :password %><br>
Confirmação Password: <br>
<%= f.password_field :password_confirmation %><br>
<%= f.submit "Submit" %>
</div>
</div>
<% end %>
Controller:
class UsersController < ApplicationController
def new
end
def create
user = User.new(user_params)
if user.save
session[:user_id] = user.id
redirect_to '/'
else
flash[:error] = 'invalid value'
end
end
private
def user_params
params.require(:user).permit(:NumeroEmpregado, :nome, :password, :password_confirmation)
end
end
Rails only can validate when you submitted your form. In this case, you can check out this guide.
In other case, if you want immediately show validate message when user enter into input, you must validate it by using Javascript. You also can use Jquery validation plugin to do that.
Hope its help :)
you should use jquery validations if you want to check if the field is empty type validations before submit https://jqueryvalidation.org/documentation/ follow this link.
Or if you are ok with validating fields on submit then in create or update action of your controller you can check from the params if that field is empty. then you can show flash messages like this
flash[:notice] = 'valid value'
flash[:error] = 'invalid value'
Or you can add model level validations on that fields http://guides.rubyonrails.org/active_record_validations.html here
You can use the Active Record Validations.
If you have a model called User, then you can specify which attributes to validate for presence using the validates method and setting the presence to true, this will check if the field on the form has been filled, also if has only whitespaces.
For instance:
class User < ApplicationRecord
validates :nome, presence: true
...
For your controller:
def create
user = User.new(user_params)
if user.save
session[:user_id] = user.id
redirect_to '/'
else
flash[:error] = 'invalid value'
redirect_to new_user_path
end
end
Redirect to the new user path with flash[:error] as "invalid value".
For your view:
<% if flash[:error] %>
<div class="error">
<%= flash[:error] %>
</div>
<% end %>
at the moment I am attempting to create a form for my website that will allow for users to input information and then the information with be POST'ed to my database for storage. I am a new ruby on rails developer so keep that in mind.
I was able to get to the point where the user could see the form and type in information but once they hit the submit button I recieve an error, and that error is
ArgumentError in StudentsController#create
wrong number of arguments (0 for 1) in app/controllers/students_controller.rb:13:in `create'
The parameters that were sent were the following
{"utf8"=>"✓",
"authenticity_token"=>"bLalQ9Ek5ziaGiGHj03AGPCTIABAgcT+o4eTgN44qv44dxNDlrGA0h2u5BSTQVTMh+YgA/mLPQee05lT7mxCsw==",
"student"=>{"first_name"=>"Andrew",
"last_name"=>"Terra"},
"commit"=>"Submit"}
Below is my students_controller.rb file.
class StudentsController < ApplicationController
def index
#students = Student.all
end
def new
#student = Student.new
end
def create
#student = Student.new(params.require[:student])
if #student.save
redirect_to students_path
end
end
def destroy
#student = Student.find_by_id(params[:id])
if #student.destroy
redirect_to students_path
end
end
end
Below is my views/students/_form.html.erb file
<%= form_for #student do |f| %>
<p>
<%= f.label :first_name %>
<%= f.text_field :first_name %>
</p>
<p>
<%= f.label :last_name %>
<%= f.text_field :last_name %>
</p>
<%= f.submit "Submit" %>
<% end %>
Below is my /views/students/index.html.erb file
<%= link_to "Create new information", new_student_path %> <br /> <hr>
<% #students.each do |fo| %>
Firstname: <%= fo.first_name %> <br />
Lastname: <%= fo.last_name %> <br />
<%= link_to "Delete info?", student_path(student), :data=>{:confirm=>"Are you sure ?"}, :method=> :delete %>
<br />
<hr>
<% end %>
Finally, here is my /views/students/new.html.erb file
Enter new info
<hr>
<%= render :partial => "form" %>
And I did remember to put resources :students in my routes file. I searched around and found other people who had previously had this problem but none of the solutions worked on the code that I have written. So I was wondering if anyone could point me in the direction of where the bug is and how exactly I can fix it. Thank you.
You need to add a new private method:
private
def student_params
params.require(:student).permit(:first_name, :last_name)
end
And then as said before change your create method to:
def create
#student = Student.new(student_params)
if #student.save
redirect_to students_path
end
end
I recommend reading the documentation on Strong Parameters - to better understand how they work. https://github.com/rails/strong_parameters
You have to change
params.require[:students] to params.require(:students)
But this is still not good way to handle your params for create action, you should add private method student_params to your controller where you would whitelist your params. Like this:
def student_params
params.require(:student).permit(:first_name, :last_name)
end
Here you can find more about it,
http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html
I have a combined/nested signup form, which registers a new organization plus a member (two models with a 1:many relationship).
When submitting invalid information to the form (that is, I fill in invalid info for the organization and no info at all for the member) it should render the combined signup form again with the error message. Instead in this scenario after submitting the invalid information, it only renders the part of the signup form for signing up the organization (without the member part of the form). If I enter invalid information for both organization and member, then it does render correctly the full combined form.
Does anyone have an idea what is wrong with the code?
The controller includes:
def new
if (logged_in?)
flash[:danger] = "You're already logged in"
redirect_to root_url
end
#organization = Organization.new
#member = #organization.members.build
end
def create
#organization = Organization.new(organizationnew_params)
if #organization.save
#organization.members.each do |single_member|
single_member.send_activation_email
end
flash[:success] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new' # This is the relevant render line.
end
end
The new view:
<%= render partial: "registrationform", locals: { url: organizations_path } %>
The partial (registrationform):
<% if local_assigns.has_key? :url %>
<%= form_for #organization, url: url do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<h4>Details of the organization:</h4>
<%= f.text_field :name, class: 'form-control' %>
<%= f.fields_for :members do |p| %>
<h4>Your personal details:</h4>
<%= p.email_field :email, class: 'form-control' %>
<%= p.password_field :password, class: 'form-control' %>
<%= p.password_field :password_confirmation, class: 'form-control' %>
<% end %>
<%= f.submit "Sign up" %>
<% end %>
<% else %>
<%= flash.now[:danger] = "Error: no url defined" %>
<% end %>
Routes:
get 'signup/organization' => 'organizations#new', as: 'register'
In your new action, you are doing #organization.members.build, which is not in your edit action. When the validation fails, it will render your new action, but won't run your new action. You could try putting #organization.members.build in the else clause of your create action like:
else
#organization.members.build if #organization.members.blank?
render 'new'
end
I have a rails application with devise, and I added to users a profile image, and a description. What I want to do is to create a page (DIFFERENT of the default registration/edit) where the users, after logged in, can set only this two atributes(image and description).
<%= form_for(:user, html: { method: :put, :multipart => true })) do |f| %>
<div class="form-group">
<%= f.label :Profile_Image %>
<%= f.file_field :image, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :Descrição %>
<%= f.text_area :description, class: "form-control", rows: "10" %>
</div>
<% end %>
I have already tried two different controllers and none of them worked:
def edit
end
def edit
#user = User.find(params[:id])
end
My config -> routes are:
get "edit" => "pages#edit"
post "edit" => "pages#edit"
But when i click submit it does nothing! I am new at rails and I am trying to figure this out for hours... How can I create a page to update only the image and the description? Thanks
You need an update method in your controller. Your edit method allows the form to render, but you need something like this:
def update
current_user.update(user_params)
end
Then you would have another method in your controller called user_params, which would look something like this. I was taught to put it under a private heading.
private
def user_params
params.require(:user).permit(:profile_image, :description)
end
I believe there is a shortcut way of including your params with your update method, but this will do.
Use registration controller devise and you should customize it.
You should have one method with the same name in one controller, you have two edit method. Change one edit method to update method ( reference : Allow users to edit their account )
pages_controller.rb
class PagesController < Devise::RegistrationsController
def edit
#user = current_user
end
def update
#user = current_user
successfully_updated = if needs_password?(#user, params)
#user.update_with_password(devise_parameter_sanitizer.for(:account_update))
else
params[:user].delete(:current_password)
#user.update_with_password(devise_parameter_sanitizer.for(:account_update))
end
if successfully_updated
set_flash_message :notice, :updated
# Sign in the user bypassing validation in case his password changed
sign_in #user, :bypass => true
redirect_to after_update_path_for(#user)
else
render "edit"
end
end
private
def needs_password?(user, params)
user.email != params[:user][:email] || params[:user][:password].present?
end
end
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_filter :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.for(:account_update) do |u|
u.permit(:description, :image, :email, :password, :password_confirmation)
end
end
end
You have wrong http verb (post), you need PUT/PATCH not POST
devise_scope :user do
get "edit" => "pages#edit"
put "update" => "pages#update"
end
On your view looks like (example and not tested)
<%= form_for(#user, :url => update_pages_path, :html => { :method => :put }) do |f| %>
<%= devise_error_messages! %>
<div class="form-group">
<%= f.label :image, "Profile Image" %>
<%= f.file_field :image, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label description, "Descrição" %>
<%= f.text_area :description, class: "form-control", rows: "10" %>
</div>
<% end %>
<%= f.submit "Save Image" %>
Just installed Rails 3.0 beta 3 in Windows 7.
And started playing with some easy examples
class SignupController < ApplicationController
def index
#user = User.new(params[:user])
if method.post? and #user.save
redirect_to :root
end
end
end
class User
def initialize(params = {})
#email = params[:email]
#passw = params[:password]
end
def save
end
end
<div align="center">
<% form_for :user do |form| %>
<%= form.label :email %>
<%= form.text_field :email %><br />
<%= form.label :password %>
<%= form.text_field :password %><br />
<%= form.submit :Register! %>
<% end %>
</div>
When I go to /signup I'm getting this error
NoMethodError in
SignupController#index
You have a nil object when you didn't
expect it! You might have expected an
instance of Array. The error occurred
while evaluating nil.[]
Is there a problem with constructor or what's wrong?Please, need your help!
I just won't use ActiveRecord or any other ORM.
You need another action to handle the post, possibly it is called create. This is how I would revise your controller:
def index
#user = User.new
end
def create
#user = User.new(params[:user])
if method.post? and #user.save
redirect_to :root
end
end
The error possibly because when the index is displayed, params variable had no content.