Rails Country_select can't save to database - ruby-on-rails

I am having trouble integrating this select country plug in (https://github.com/scudco/country_select_test) into my test application. I installed it and put it into my database. It shows up when I type my id into the rails console but it always comes up as nil. Here is my view.haml:
.form-group
= f.input :country_code, autofocus: true, :class => "form-control"
.form-group
= f.input :address, autofocus: false, :class => "form-control"
Here is the migration I recently made:
class AddCountryCodeToUsers < ActiveRecord::Migration
def change
add_column :users, :country_code, :string
end
end
The output of my console:
updated_at: "2015-08-07 15:29:26", address: " ", country_code: nil>
I have nothing about the :country_code in my users.rb file. I used to have the assert country_code in their but it didn't change anything when I took it out. Thank you to everyone who helps me out. I'm still a noob at ruby on rails.

You probably miss to allow the :country_code param in your UsersController due to strong_parameters
In your controller you should have something like
def users_params
params.require(:user).permit(...)
end
You need to ensure, in the permit method, that :country_code is called too. For example:
params.require(:user).permit(:country_code, :email, :password, :password_confirmation)

Related

Ruby On Rails Change Column to Null, Not Work?

I command in Terminal to change on column in database to not null, but It seems not work.
rails g migration change_column_null :Speaker, :surname, false
I got a file ChangeColumnNull But inside, it is nothing.
class ChangeColumnNull < ActiveRecord::Migration
def change
end
end
Lecture Controller (Def Create):
class CplecturesController < ApplicationController
layout 'cp_layout'
def create
#lecture = Lecture.new(lecture_params)
#lecture.save
redirect_to #lecture
end
private
def lecture_params
params.require(:lecture).permit(:lecture_title, :lecture_day, :column, :start_time, :end_time, :registered_speakers, :guest_speakers, :description)
end
end
Forms
<%= form_for :lecture, url:lectures_path do |f| %>
<form>
<div class="form-group">
<%=label_tag "Lecture Title" %><br>
<%= f.text_field :lecture_title, :class => "form-control", :placeholder => "Example: Why is Wordpress the best?" %>
</div>
Erase that migration and write a blank migration with a better name and then fill it out by setting a default value. If you have a default value it will never be null.
rails g migration ChangeColumnOnTableName
Then inside that migration do the following:
change_column :name_of_table, :name_of_column, :data_type_of_column, :null => false
If you're only worried about it being null based on what a user enters, you could simply add a validation that requires it. In your model:
validates :name_of_column, presence: true
if you are using latest ruby (2.5+) Here is the migration script to change fields from NOT NULL to NULL
class ChangeEmailPasswordToNullableUsers < ActiveRecord::Migration[5.2]
def change
change_column_null :users, :email, true
change_column_null :users, :password, true
end
end

Rails update_attributes using has_secure_password

I am working in a project where users can either have admin: true / false. The application will only let admin users login in to the system, the other users are just clients whose settings only admins can edit. This is some sort of commerce application.(Rails 3.2.13)
I would like to keep both concepts in the same table since in the future there will possibly be the option of logging in for non-admin users and interact with their profiles, so all the logic will be already implemented.
I've got this User resource:
ActiveRecord::Schema.define(:version => 20131204200554) do
create_table "users", :force => true do |t|
t.string "name"
t.string "surname"
t.boolean "admin"
t.string "password_digest"
t.string "email"
t.string "auth_token"
end
end
This is the user model:
class User < ActiveRecord::Base
has_secure_password
attr_accessible :name, :surname,:email, :password, :password_confirmation
validates :name, presence:true, length: { maximum:50}
validates :first_surname, presence:true, length: { maximum:50}
VALID_EMAIL_REGEX= /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true,format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive:false}
validates :password, length:{minimum:6}
validates :password_confirmation, presence:true
before_save{ self.email.downcase! }
before_save :generate_auth_token
private
def generate_auth_token
self.auth_token=SecureRandom.urlsafe_base64
end
end
And I am trying to implement the functionality of User editing, however I only want to allow the editing of name, surname and email. Hence, I present only those fields in the form:
<%= form_for(#user) do |f| %>
<%= f.label :name,"Name" %>
<%= f.text_field :name %>
<%= f.label :surname,"Surname" %>
<%= f.text_field :surname %>
<%= f.label :email,"Email" %>
<%= f.text_field :email %>
<%= f.submit "Save" %>
I am trying to accomplish the goal with this code:
def update
#user = User.find(params[:id])
if #user.update_attributes(params[:user])
# Handle a successful update.
flash[:success]="User updated successfully"
redirect_to #user
else
flash[:danger]="Error updating user"
render 'edit'
end
end
My problem is that when trying to update_attributes I get not unexpectedly an error validating password/password_confirmation, but since I'm using has_secure_password, these fields do not exist in the database, only password_digest. I am thinking about the best option to accomplish all this:
Update #user object with new field values.
Reflect this change in User table.
Run the validations, i.e. email validation.
While using has_secure_password. These are the options so far:
Use of update_attribute(best so far).
1.1 Pro: updates the User table
1.2 Con: I have to update_attribute(field1) for each of the fields, so more lines of code
1.3 Con: Apparently this method no longer exists in Rails 4, problem in case an upgrade is desirable in the future.
1.4 Con: No validations
Use of #user.attributes=params[:user] in the controller method
2.1 Pro: Updates multiple fields at once.
2.2 Con: Does not update the User table.
User of update_attributes
3.1 Pro: Both multiple fields and table update
3.2 Con: Not working ( duh!)
Suggestions?
It looks like you want to validate the presence of password on create only (also notice more concise way to validate password confirmation):
validates :password, length:{minimum:6}, confirmation: true, on: :create
You can then use update_attributes
You may want to restrict what params can be submitted by using strong params:
Gem: https://github.com/rails/strong_parameters
also included in Rails 4 http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html

Rails seed.rb as admin

I've rolled out my own authentication/authorization system based on Hartl's for my app. I wanted to allow admins to make other users admins, so I did this in my user.rb file:
attr_accessible :name, :email, :password, :password_confirmation, :order_id
attr_accessible :name, :email, :password, :password_confirmation, :order_id, :admin, :as => :administrator
and put this in my user update action:
def update
if current_user.admin?
if #user.update_attributes(params[:user], :as => :administrator)
This works great for me, but it's getting annoying to have to go into console and type
User.find(2).toggle!(:admin)
or whatever, whenever I want to make my first admin user after a db reset, or, for that matter, to have to use the console or individual edits to make other admins. I'd love it if I could seed ":as => administrator", so I tried this in my seed.rb file, but it doesn't work (mass-assign error):
admin = User.create(
:name => "My Name",
:email => "my email",
:password => "password",
:password_confirmation => "password",
:admin => true,
:as => :administrator
)
Any idea if there's a way to do this? It'd make my life a lot easier.
The simplest solution I found was to toggle admin in the seeds.rb file right after creating the user. This way, I avoid "mass" assignment without having to assign in the console. So:
admin = User.create(
:name => "My Name",
:email => "my email",
:password => "password",
:password_confirmation => "password"
)
admin.toggle!(:admin)
# I assume "admin.update_attribute(:admin, true)" would work as well.
Since you have a mass-assign error, I think you should only keep the second line of attr_accessible in User.rb and discard the first line, which is causing the error.
I was looking to perform the same thing and end up doing like this in seeds.rb:
# db/seeds.rb
users = User.create({email: 'email#admin.com', username: 'admin', password: 'sEcReT', password_confirmation: 'sEcReT', role: 'admin'},
:as => :admin)
# models/user.rb
attr_accessible :email, :username, :password, :password_confirmation, :role, :as => :admin

Rails_admin new model configuration

I just installed Rails Admin, and I want to have a model called "Business". Through Rails Admin, I want to be able to create new businesses, edit them, etc. I've written the code for the model already, but I don't know how to use the rails_admin.rb file to configure the model. Here's what I have so far.
Business.rb
class Business < ActiveRecord::Base
#attr_accessible :title, :body
attr_accessible :name, :website, :phone, :manager, :email, :type, :mobile,
:foursquare, :facebook, :yelp, :google
validates_presence_of :name, :website, :phone, :manager, :email, :type, :mobile,
:foursquare, :facebook, :yelp, :google
def type_enum
['Agencies', 'Automotive', 'Contractor', 'Country Club', 'Entertainment',
'Restaurant and Bar', 'Funeral', 'Furniture', 'Healthcare', 'Laundry', 'Legal',
'Office', 'Other', 'Personal Trainer', 'Real Estate', 'Religious', 'Retail',
'Salon', 'Wedding Hall']
end
def mobile_enum
['Yes', 'No']
end
def foursquare_enum
['Yes', 'No']
end
def facebook_enum
['Yes', 'No']
end
def yelp_enum
['Yes', 'No']
end
def google_enum
['Yes', 'No']
end
end
What should I include in my rails_admin.rb? Ideally I want to have text fields to enter data for all the fields, except for the ones for which I created 'enum' methods - these should be dropdown menus. I'm new to Rails Admin, and relatively new to rails so I appreciate your help greatly.
Thanks!
Your configuration will look something like this:
RailsAdmin.config do |config|
config.model Business do
list do
field :name
field :website
end
show do
# e.g. include_all_fields
end
edit do
# e.g. include_all_fields
# exclude_fields :website
end
end
end
You can read additional field configuration at the RailsAdmin field configuration wiki page.

Validates acceptance always failing

I can't see what I'm missing, but something is obviously not right.
In model:
validates :terms, :acceptance => true, :on => :update
Trying a few options:
>> a = Factory(:blog_agreement)
=> #<BlogAgreement id: 54, terms: false, created_at: "2011-01-20 11:33:03", updated_at: "2011-01-20 11:33:03", accept_code: "fa27698206bb15a6fba41857f12841c363c0e291", user_id: 874>
>> a.terms
=> false
>> a.terms = true
=> true
>> a.save
=> false
>> a.terms = "1"
=> "1"
>> a.save
=> false
>> a.terms = 1
=> 1
>> a.save
=> false
>> a.errors.full_messages
=> ["Terms must be accepted"]
Updated answer..
So it turns out that the problem was having terms as an actual column in the table. In general validates_acceptance_of is used without such a column, in which case it defines an attribute accessor and uses that for its validation.
In order for validates_acceptance_of to work when it maps to a real table column it is necessary to pass the :accept option, like:
validates :terms, :acceptance => {:accept => true}
The reason for this has to do with typecasting in Active Record. When the named attribute actually exists, AR performs typecasting based on the database column type. In most cases the acceptance column will be defined as a boolean and so model_object.terms will return true or false.
When there's no such column attr_accessor :terms simply returns the value passed in to the model object from the params hash which will normally be "1" from a checkbox field.
In the case of someone has the same problem like me with devise, i add this answer:
i added to the devise's registration form:
sign_up.html.erb
<%= f.check_box :terms_of_service %>
user.rb
validates, :terms_of_service, acceptance: true
i forgot to add :terms_of_service inside my configured_permitted_parameters and devise ignored the checkbox state.
application_controller.rb
before_filter :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:email, :password, :password_confirmation, :terms_of_service)}
end
The configure_permitted_parameters method is used by devise for know what params he should be save in addition of email and password.
I had to use this format:
validates :accpeted_terms, :acceptance => {:accept => true}
validates_acceptance_of :terms, :accept => true
I found Candland's answer above for validates acceptance to be correct in Rails 3.1. This is how I set up my Rails 3.1.3 app to record the acceptance to the database.
In the migration,
class AddTermsToAccount < ActiveRecord::Migration
def change
add_column :accounts, :terms_of_service, :boolean, :default => false
end
end
In the model,
attr_accessible :terms_of_service
validates :terms_of_service, :acceptance => {:accept => true}
In the form,
<%= f.check_box :terms_of_service %>
<%= f.label :terms_of_service %>
I have tried this from Angular JS and Rails 4. Angular send parameter with true value but rails did not recognize true.
It can receive an :accept option, which determines the value that will
be considered acceptance. It defaults to "1" and can be easily
changed.
So, I change into this:
class Person < ActiveRecord::Base
validates :terms_of_service, acceptance: { accept: true }
end
If you have default parameter is 1 or 0. Try to do this:
class Person < ActiveRecord::Base
validates :terms_of_service, acceptance: true
end
This is for more documentation. acceptance validation.
I hope this help you.
A call to a factory creates the record, so your subsequent calls to save are in fact updates, so your validation fails as intended. Try it without the factory and it should work.
if you have a basic checkbox in your view, such as
<%= builder.check_box :agreement %>
just put this line in your model
validates :agreement, :acceptance => true
which uses the default "1" generated by the check_box view helper

Resources