Why aren't parameters populating a new instance of a class? - ruby-on-rails

I am submitting a form into a CorporateContactFormsController. I can see the parameters are being passed but they are not being added to the instantiated class.
def create
#contact_form = CorporateContactForm.new(corporate_contact_form_params)
raise
end
private
def corporate_contact_form_params
params.require(:corporate_contact_form).permit(:firstname, :surname, :contact_number, :email, :company_name, :method_of_payment, :number_of_employees, :comments, :contact_type)
end
This is from better-errors gem
>> corporate_contact_form_params
=> {"firstname"=>"qwertyui", "surname"=>"wertyuio", "contact_number"=>"wertyuio", "email"=>"qwdqwd#iugh.com", "company_name"=>"wqedfwefwef", "method_of_payment"=>"Other", "number_of_employees"=>"1-50", "comments"=>"qwdqwdqwdqwdqwdqwdwqd", "contact_type"=>"employee"}
>> #contact_form = CorporateContactForm.new(corporate_contact_form_params)
=> #<CorporateContactForm id: nil, contact_type: nil, firstname: nil, surname: nil, contact_number: nil, email: nil, company_name: nil, company_website: nil, position_in_company: nil, location: nil, number_of_employees: nil, method_of_payment: nil, comments: nil, created_at: nil, updated_at: nil>
Why aren't the parameters populating the new instance of the class?
I am using rails 4.0
update
model
class CorporateContactForm < ActiveRecord::Base
EMPLOYEE = 'employee'
EMPLOYER = 'employer'
CONTACT_TYPE = [EMPLOYEE, EMPLOYER]
ONE_TO_FIFITY = "1-50"
FIFTY_TO_ONEHUNDRED = "50-100"
ONEHUNDRED_OR_MORE = "100+"
EMPLOYEE_COUNT = [ONE_TO_FIFITY, FIFTY_TO_ONEHUNDRED, ONEHUNDRED_OR_MORE]
OTHER = "Other"
COMPANY = "Company funded"
METHOD_OF_PAYMENT = [COMPANY, OTHER]
validates :contact_type, inclusion: CONTACT_TYPE, presence: true
validates :number_of_employees, inclusion: EMPLOYEE_COUNT, presence: true
validates :firstname, presence: :true
validates :email, presence: :true
validates :company_name, presence: :true
validates :email, presence: :true
validate :blanks_to_nils
private
def blanks_to_nils
blank_to_nil :surname
blank_to_nil :contact_number
blank_to_nil :position_in_company
blank_to_nil :location
blank_to_nil :method_of_payment
blank_to_nil :comments
end

Related

Create child association from controller

I have 2 associated models and am trying to create the child from the parent's controller:
class Purchase < ActiveRecord::Base
has_many :comments, as: :commentable, dependent: :destroy
accepts_nested_attributes_for :comments, reject_if: :all_blank, allow_destroy: true
end
class Comment < ActiveRecord::Base
belongs_to :employee
belongs_to :commentable, polymorphic: true
validates_presence_of :body, :employee_id, :commentable_id, :commentable_type
end
In my controller I accept the params for comment:
def create
#purchase = Purchase.new(purchase_params)
if #purchase[:discount] && #purchase[:discount] > 0
#purchase[:discount] = #purchase[:discount].round(3)
end
if #purchase.save
render json: #purchase, status: :created
else
p "errors", #purchase.errors
render json: #purchase.errors.full_messages, status: :unprocessable_entity
end
end
private
def purchase_params
params.require(:purchase).permit(
:sale_type, :weeks, :weekly_cost, :date, :discount, :client_id, :id, :created_at, :updated_at, :employee_id, :consultation_id, :program_id, :purchaseable_type, :purchaseable_id,
comments_attributes: [:body, :id, :employee_id, :commentable_type]
)
end
When I attempt to create the purchase with the following params, I get the error:
purchase = {
client_id: client.id,
weeks: 5,
weekly_cost: 295,
comments_attributes: [{
employee_id: employee.id,
body: "This is a test",
commentable_type: "Purchase"
}]
}
#<ActiveModel::Errors:0x00007fb0ef3849e0 #base=#<Purchase id: nil, weeks: 5, weekly_cost: 295.0, created_at: nil, updated_at: nil, client_id: 18, discount: nil, employee_id: nil, comment: nil, referral_used: false, deleted_at: nil, date: nil, sale_type: nil, purchaseable_type: nil, purchaseable_id: nil, program_id: nil>, #messages={:"comments.commentable_id"=>["can't be blank"]}, #details={:"comments.commentable_id"=>[{:error=>:blank}]}>
There's no way to know the commentable_id before saving the purchase. What am I missing?

Model test in Ruby

I've some problems with my model tests in ruby. When I try to use a test of validation, the test produces an error. I created a new model (child model) which has the following validations
class Child < ApplicationRecord
has_many :relations, :dependent => :destroy
accepts_nested_attributes_for :relations
belongs_to :user
validates :user, presence: true
validates :name, presence: true, length: { maximum: 50 }
validates :city, presence: true, :on => :create
validates :postalcode, presence: true, numericality: true
validates :streed, presence: true
validates :add_number, presence: true
validates :disability, presence:true, inclusion: { in: [true, false] }
validates :halal, presence:true, inclusion: { in: [true, false] }
validates :koscha, presence:true, inclusion: { in: [true, false] }
validates :vegetarian, presence:true, inclusion: { in: [true, false] }
validates :vegan, presence:true, inclusion: { in: [true, false] }
validates :allday, presence:true, inclusion: { in: [true, false] }
validates :gender, presence: true
I would like to test my model and wanna use as first test the validation of the child:
def setup
#child = Child.new(name: "Example Child", city: "Example City", postalcode: 13, streed: "Example Street",
add_number: 3, disability: true, gender: 1, halal: true, koscha: false,
vegetarian: false, vegan: false, allday:true, user: "hallo")
end
test "should be valid" do
assert #child.valid?
end
and my fixtures for the children look like this:
one:
name: MyString
city: MyString
postalcode: 1
streed: MyString
add_number: 1
disability: false
halal: false
koscha: false
vegetarian: false
vegan: false
allday: false
gender: 1
user_id: 3
I have the problem, that my validation test produces the following error false to be truth and I can't see, what I've done wrong...
I think, it's a very simple fault...
Thank you for your help!
my validation test produces the following error false to be truth and I can't see, what I've done wrong
This means that #child.valid? returns false. Not what assert expects.
I too don't see what you did wrong. Most likely, some validation failing. It's trivial to find out which one. Just inspect #child.errors. Like this, for example.
test "should be valid" do
is_valid = #child.valid? # trigger validation
p #child.errors unless is_valid
assert is_valid
end
I'm betting on this one:
user: "hallo"
This doesn't look like a valid user object.

controller's before_save methods aren't called in testing

Following is rails-api only app.
In users_controller.rb
def sign_up
#user = User.new(user_params)
if #user.save
user = {}
user[:name] = #user.name
user[:email] = #user.email
user[:access_token] = #user.auth_token
user[:message] = "Successfully Signed up"
render json: user, status: 200
else
render json: #user.errors, status: :unprocessable_entity
end
end
private
def user_params
params.permit(:name, :email, :password, :password_confirmation)
end
In model/user.rb
attr_accessor :password
before_save :encrypt_password, :generate_token
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, :confirmation => true, presence: true, :length => {:within => 6..20}
validates_presence_of :password_salt, :password_hash
validates_presence_of :auth_token
In test/controllers/users_controller_test.rb
test "should create user" do
assert_difference('User.count') do
post :sign_up, {email: 'user_3#example.com', name: 'user_3', password: 12345678, password_confirmation: 12345678}
end
end
user model attributes are:
name email password_hash password_salt auth_token
The test above is failing b'cos #user.errors shows
<ActiveModel::Errors:0x007fd826117140 #base=#<User id: nil, name: "user_3", email: "user_3#example.com", password_hash: nil, password_salt: nil, auth_token: nil, created_at: nil, updated_at: nil>, #messages={:password_salt=>["can't be blank"], :password_hash=>["can't be blank"], :auth_token=>["can't be blank"]}>
On #user.save before_save :encrypt_password, :generate_token aren't called.
Using gem 'bcrypt' to store the password as hash.
How do I correct this?
Instead of before_save :encrypt_password, :generate_token use before_validation :encrypt_password, :generate_token. Code in encrypt_password and generate_token is not triggered because you validate model data first and since data is not valid there is no need to trigger before_save because record would not be saved anyway

How to make sure child object is valid while saving parent?

let say that I have two class
class User
attr_accessible :name
has_one :address
validates :name, :presence => true
validates_associated :address
end
class Address
attr_accessible :country, :user_id
belongs_to :user
validates :country, :presence => true
validates :user, :presence => true
end
Now when i try to create invalid Address then it fails(which is good)
a = Address.new
a.valid? #=> false
But when i build User with invalid Address then it pass(which is bad)
u = User.first
u.build_address
u.valid? #=> true
u.save #=> true
Due to this User has Address with country => nil.
How can i tell Rails to not save Address if its invalid?
FIXED: I fixed this by adding follow line to the code. Thank you everyone.
validates_associated :address, :if => :address
class User
attr_accessible :name
has_one :address, :validate => true
validates :name, :presence => true
validates_associated :address
end
You need to also validate that an Address is actually present for User:
class User < ActiveRecord::Base
validates :address, :associated => true, :presence => true
end
With that in place, I get:
>> u = User.first
=> #<User id: 1, name: "Bob", created_at: "2013-10-09 15:17:21", updated_at: "2013-10-09 15:17:21">
>> u.build_address
=> #<Address id: nil, user_id: 1, country: nil, created_at: nil, updated_at: nil>
>> u.valid?
=> false
>> u.errors
=> #<ActiveModel::Errors:0x007fe1d6919b18 #base=#<User id: 1, name: "Bob", created_at: "2013-10-09 15:17:21", updated_at: "2013-10-09 15:17:21">, #messages={:address=>["is invalid"]}>
>> u.address.errors
=> #<ActiveModel::Errors:0x007fe1d69197a8 #base=#<Address id: nil, user_id: 1, country: nil, created_at: nil, updated_at: nil>, #messages={:country=>["can't be blank"]}>

Fabricate isn't saving attributes

I am having trouble getting one of my rspec/capybara integration specs to pass using the Fabricate gem.
Here is my spec:
it "shows current node as top node on page" do
#node = Fabricate(:node)
visit node_path(#node)
page.should have_content(#node.title)
end
My Fabricator:
Fabricator(:node) do
title { Faker::Lorem.words(3).join(" ") }
description {Faker::Lorem.paragraphs(3).join("\n") }
end
My node's show action:
def show
#node = Node.find(params[:id])
end
My show.html.haml:
%h1= #node.title
The output of my spec:
1) Node shows current node as top node on page
Failure/Error: page.should have_content(#node.title)
expected #has_content?("nostrum qui sed") to return true, got false
And lastly, I put a save_and_open_page, a debug(params) and debug(#node) on the view, here's that output:
action: show
controller: nodes
id: "1"
--- !ruby/object:Node
attributes:
id: "1"
title:
description:
created_at: 2011-06-01 03:14:45.645663
updated_at: 2011-06-01 03:14:45.645663
attributes_cache: {}
changed_attributes: {}
destroyed: false
marked_for_destruction: false
new_record: false
previously_changed: {}
readonly: false
Anybody have any idea why title and description are not being saved to the DB?
Thanks in advance!
----------------- update 6-1 ------------------------
My node model:
class Node < ActiveRecord::Base
attr_accessor :title, :description
validates :title, :presence => true
validates :description, :presence => true
end
In between
#node = Fabricate(:node)
visit node_path(#node)
Try inserting a save! to see if it's a validation issue of some kind:
#node = Fabricate(:node)
#node.save!
visit node_path(#node)
You should probably do a:
class Node < ActiveRecord::Base
attr_accessible :title, :description
validates :title, :presence => true
validates :description, :presence => true
end
Your Model should be
class Node < ActiveRecord::Base
validates :title, :presence => true
validates :description, :presence => true
end

Resources