Simple_form submit button its not working - ruby-on-rails

Im new on rails. Im trying to validate the input value in a simple_form. If the values correct then redirect to a external url.
But the submit button its not working.
My model:
class Course < ApplicationRecord
validates :keyword, presence: true
validates :keyword, inclusion: { in: %w(marketing pepe),
message: "%{value} its not valid " }
end
My controller
def new
#course = Course.new
end
def create
#course = Course.new(params[:keyword])
if #course.keyword == "marketing"
#course.save
redirect_to ('https://res.cloudinary.com/...pdf')
end
end
my view
<h2>Do you have a code?</h2>
<%= simple_form_for #course do |f| %>
<%= f.input :keyword, label: 'Your keyword please', placeholder: "puts here" %>
<%= f.submit 'take it' %>
<% end %>
Any one can help me?

Related

Check_box_tag doesn't retain value in rails app

I have a model called "Clients". The Clients model belongs to the Users model (Users model is associated with devise). There is another model called "sellers", but they aren't involved in the question. The Client can do payments to me manually (cash only). When the client does this payment, I give them access to more pages in the website. To do this, I added a boolean variable called "paid" to my clients and then the admin(me) can go to their client profile, update the paid status from 'unpaid' to 'paid' through a checkbox. Only the admin can view the checkbox.
This is the form partial for updating client information:
<%= simple_form_for #client do |f| %>
<%= f.input :name, label: 'Full name', error: 'Full name is mandatory' %>
<%= f.input :company, label: 'Name of company' %>
<%= f.input :position, label: 'Position you hold at your company' %>
<%= f.input :number, label: 'Phone number' %>
<%= f.input :email, label: 'Enter email address' %>
<%= f.file_field :emp_img, label: 'Profile picture' %>
<%= check_box_tag 'paid', 'yes', false %>
<%= f.button :submit %>
<% end %>
Then my client controller is:
class ClientController < ApplicationController
before_action :find_client, only: [:show, :edit, :update, :destroy]
def index
end
def show
end
def new
#client = current_user.build_client
end
def create
#client = current_user.build_client(client_params)
if #client.save
redirect_to clients_path
else
render 'new'
end
end
def edit
end
def update
end
def destroy
#client.destroy
redirect_to root_path
end
private
def client_params
if current_user.user_type == :admin
params[:client][:paid] = params[:client][:paid] == 'yes'
params.require(:client).permit(:paid, :name, :company, :position, :number, :email, :client_img)
else
params.require(:client).permit(:name, :company, :position, :number, :email, :client_img)
end
end
def find_client
#client = Client.find(params[:id])
end
end
When I go to the client profile, and click on "update" info, I get the form partial, in that, the check box is not checked. I click it and update the profile, no errors, takes me back to the profile. But when I click update again, the check box is unchecked. It doesn't retain the value of the check box ONLY. Everything else is retained. Like the name, company and all that. When I go into the rails c, the paid variable is still false even if I click on it and update it. Does anyone know why it might be so?
Use check_box form helper in place of check_box_tag into the form, and remove line from client_params method:
params[:client][:paid] = params[:client][:paid] == 'yes'

Rails autocomplete textfield won't work

Followed this guide by railscasts to setup autocompletion on collection_select.
https://www.youtube.com/watch?v=M7yhPlIehFA
In my example I'm trying to create a chatroom with a game related.
MODEL
belongs_to :game
validates :game, presence: true
def game_name
game.try(:name)
end
def game_name=(name)
self.game = Game.where(name: name).first_or_create if name.present?
end
CONTROLLER
def create
#room = current_user.chatrooms.build(room_params)
if #room.save
redirect_to #room
else
render 'new'
end
end
def room_params
params.require(:chatroom).permit(:title, :description, :game_id)
end
HTML
<%= simple_form_for #room do |f| %>
<p class="ftitle">Chatroom title</p>
<%= f.input :title, label: false %>
<p class="ftitle">Chatroom description</p>
<%= f.input :description, label: false %>
<p class="ftitle">Select related game</p>
<%= f.text_field :game_name, data: { autocomplete_source: Game.order(:name).map(&:name) } %>
<%= f.button :submit %>
<% end %>
It works fine until I try to create a chatroom with a game attached. It won't attach the game_id as a game. Not sure why.
Thanks.
Trying to link the game based on name seems quite brittle and open to future abuse.
However if that's really what you want to do, add :game_name to the .permit method in room_params.
It would be more robust to pass through an ID here, rather than plain text.

Rails Sorcery update attributes of model without password

I use sorcery for user authentication in a rails 4.1 application. Everything works fine. But when I try to update specific attributes of the user model (which is authenticated by sorcery), I get an error that the password is blank and is too short.
Here's a snippet from the console
> user = User.last
=> # I get the user
> user.update(about_me: "I'm a user")
=> false
> user.update(about_me: "I'm a user", password: "secret")
=> true
Here's my model code
app/models/user.rb
class User < ActiveRecord::Base
authenticates_with_sorcery!
validates :password, presence: true, length: { minimum: 6 }
.....
end
My controller code
app/controllers/users_controller.rb
class UsersController < ApplicationController
.....
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update(user_params)
redirect_to #user
flash[:notice] = "Profile successfully updated"
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:username, :name, :email, :password, :about_me)
end
end
And my update form
app/views/users/edit.html.erb
<%= form_for #user, method: :put do |f| %>
<% if #user.errors.any? %>
<div class="alert">
<p><%= pluralize(#user.errors.count, 'error') %></p>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.text_field :username, placeholder: 'Username' %>
<%= f.text_field :name, placeholder: 'Name' %>
<%= f.email_field :email, placeholder: 'Email' %>
<%= f.text_area :about_me, placeholder: 'About me' %>
<%= f.password_field :password, placeholder: 'Password' %>
<%= f.submit 'Save Changes', class: 'button' %>
<% end %>
If I remove the password field from the form, I get errors about the password being blank and about it's length.
Is this something to do with sorcery or is it something I'm missing with rails itself?
Is there a better way to update let's say only the email field without affecting anything else?
class User < ActiveRecord::Base
authenticates_with_sorcery!
validates :password, presence: true, length: { minimum: 6 }, if: :new_user?
private
def new_user?
new_record?
end
end
The validation will be checked only if it's a new_record, for which we have added our own private validation method new_user?. This function will return true during your normal signups/registrations. Hence, at those signups only the password validation will be needed.
During the edit, off course the user will be an existing user / new_record? will return false. Hence the validation for password will be skipped.
2nd way:
class User < ActiveRecord::Base
attr_accessor :skip_password
validates :password, presence: true, length: { minimum: 6 }, unless: :skip_password
end
#users_controller.rb
def update
#user = User.find(params[:id])
#user.skip_password = true
if #user.update(user_params)
redirect_to #user
else
render 'edit'
end
end
Here we have added our own custom attr_accessor skip_password. If the skip_password value is set to true, then during edit/update the password validation will be skipped.
I hope both of those ways will help you :)
If someone looks for this topic in future, it is possible to use changes map of ActiveRecord model:
class User < ActiveRecord::Base
authenticates_with_sorcery!
validates :password, presence: true, length: { minimum: 6 }, if: -> {new_record? || changes[:crypted_password]}
.....
end
where :crypted_password is the value of sorcery_config.crypted_password_attribute_name.
Also currently such condition of validates pointed in Simple Password Authentication sorcery wiki article.

How to reject blank and empty attributes during sign_up form?

I have
Model
class User < ActiveRecord::Base
attr_accessible :email
validates :email,
presence: true
serialize :data, ActiveRecord::Coders::Hstore
%w[zipcode first_name].each do |key|
attr_accessible key
define_method(key) do
data && data[key]
end
define_method("#{key}=") do |value|
self.data = (data || {}).merge(key => value)
end
end
end
Controller
class UsersController < ApplicationController
def create
#user = User.find_or_initialize_by_email(params[:user][:email])
if #user.update_attributes(params[:user])
redirect_to :back, notice: "Thanks for sign up!"
else
render "pages/home"
end
end
end
View with client side validation
<%= simple_form_for User.new, validate: true do |f| %>
<%= f.input :email %>
<%= f.input :first_name %>
<%= f.input :zipcode %>
<%= f.button :submit, 'Sign up' %>
<% end %>
First question: I would like to update existing user record but not if param is "" or " ", how to achieve this?
Second question: Should I use create action to do that? Maybe update will be more clear. But this form also create an user object.
Third question: Is any chance to add uniqueness validation to email attribute? Right now my client-side validation do not allow do that.
First: To disallow updating a field with empty strings, set allow_blank: false you could also do allow_nil: false. Add these to your validations in your model.
Second: N/A
Third: Simply add uniqueness: true to your email validation in your model.
Read more here

Ruby on Rails: How would i stay on the same page if the post is not saved?

def create
#addpost = Post.new params[:data]
if #addpost.save
flash[:notice] = "Post has been saved successfully."
redirect_to posts_path
else
flash[:notice] = "Post can not be saved, please enter information."
end
end
If the post is not saved then it redirects to http://0.0.0.0:3000/posts , but i need to stay on the page, with text input fields so that user can input data.
post model
class Post < ActiveRecord::Base
has_many :comments
validates :title, :presence => true
validates :content, :presence => true
validates :category_id, :presence => true
validates :tags, :presence => true
end
new method
def new
#arr_select = { 1=>"One",2=>"Two" ,3=>"Three" }
#categories_select = Category.all.collect {|c| [ c.category_name, c.id ] }
end
new.html.erb
<h3>Add post</h3>
<%= form_tag :controller=>'posts', :action=>'create' do %>
<%= label :q, :Title %>
<%= text_field :data, :title, :class => :addtextsize %><br/>
<%= label :q, :Content %>
<%= text_area :data, :content, :rows=>10 , :class => :addtextarea %><br/>
<%= label :q, :Category %>
<%= select :data, :category_id, #categories_select %><br/>
<%= label :q, :Tags %>
<%= text_field :data, :tags, :class => :addtextsize %><br/>
<%= label :q, :Submit %>
<%= submit_tag "Add Post" %>
<% end %>
What should i do ?
flash.now with render is what you're looking for.
flash.now[:notice] = "Post can not be saved, please enter information."
render :new
Also instead of
flash[:notice] = "Post has been saved successfully."
redirect_to posts_path
you can just write
redirect_to posts_path, :notice => "Post has been saved successfully."
and it will do the same thing. It works only with redirect_to though, not with render!
Something like this should do what you want:
flash[:notice] = "Post can not be saved, please enter information."
render :new
UPDATE: You updated your question so I have to update my answer. Render is the right way to do this. However, it looks like you load some categories and some other collection of stuff in your new method. Those same instance variables should be available to your create method. The cleanest way to do this is put them into another method and have that method used as a before_filter applied to both create and new. Something like this:
before_filter :load_stuff, :only => [:create, :new]
def load_stuff
#arr_select = { 1=>"One",2=>"Two" ,3=>"Three" }
#categories_select = Category.all.collect {|c| [ c.category_name, c.id ] }
end
Then your new method is pretty much blank and calling render :new in your create method should work.
Hey this answer is super late but thought I'd add it for anyone that comes across it. Probably the most simple solution for what you want to achieve is to add required: true to all of the form inputs you want filled out. E.g
f.text_field :title, required: true, class: "whateverclassyouwant"
This way the form will ONLY be submitted if these fields have been filled in correctly and if not an error flash message will pop up on the field that it needs to be completed. The default flash messages that pop up can be custom styled also, Google how to do so.
This way you can remove the else redirect all together in your create method as it will never get to that point, and just have the if save, flash success etc.

Resources