can't convert symbol into integer error when saving user - ruby-on-rails

So here is my issue. I have been working with users I created at the beginning of my project for a month now. Today I switched from sqllite to sqlserver to meet client requirements and when I went to use my registration form to create a new user I got the following error:
can't convert Symbol into Integer
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"51nF50CYGNqz3N4o7TUYSyWeTadulXojQBPqERjvlcY=",
"user"=>{
"email"=>"test#blizzardlabs.com",
"login"=>"bgarrison",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]",
"profile_attributes"=>{
"prefix"=>"",
"first_name"=>"Bill",
"last_name"=>"Garrison",
"suffix"=>"",
"birthday"=>"1983-06-01",
"phone_numbers_attributes"=>{
"0"=>{
"info"=>"1234567890",
"label"=>"Cell"
}
}
}
},
"commit"=>"Register"}
I have a feeling that at some point I messed up the registration process but I can't for the life of me figure out where. User-> has_one profile-> has_many phone_numbers.
User Controller:
def create
#user = User.new(params[:user])
if #user.save
#profile = #user.profile
flash[:notice] = "Your account has been created."
redirect_to(#user)
else
flash[:notice] = "There was a problem creating you."
render :action => :new, :layout => 'logged_out'
end
end
User Model:
class User < ActiveRecord::Base
# Accessible attributes
attr_accessible :login,
:email,
:password,
:password_confirmation,
:profile_attributes,
:active
# Associations
has_one :profile, dependent: :destroy, autosave: true
# Allows for a profile hash in user creation (stored in :profile_attributes)
accepts_nested_attributes_for :profile
Profile Model:
class Profile < ActiveRecord::Base
# Accessible Attributes
attr_accessible :birthday,
:company_id,
:first_name,
:last_name,
:prefix,
:suffix,
:phone_numbers_attributes,
:addresses_attributes
# Model Associations
has_many :phone_numbers, :as => :contactable, :class_name => "PhoneNumber", autosave: true
accepts_nested_attributes_for :phone_numbers, allow_destroy: true, reject_if: :all_blan
Any help would be appreciated. Thanks!
Update:1 Also, I have tested some and realized if I leave out the phone number then it works.....if I then update using the same form and add a phone number everything works fine.

Nested attributes should be passed in as Array:
"user"=>{
"email"=>"test#blizzardlabs.com",
"login"=>"bgarrison",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]",
"profile_attributes"=>[
{
"prefix"=>"",
"first_name"=>"Bill",
"last_name"=>"Garrison",
"suffix"=>"",
"birthday"=>"1983-06-01",
"phone_numbers_attributes"=>{
"0"=>{
"info"=>"1234567890",
"label"=>"Cell"
}
}
}
]
}

So, after a couple days of banging my head against the wall I have finally figured this out. However to understand it I need to explain my model's a bit better.
Basically, from above you can see that a User has a profile which has many phone_numbers and addresses through a polymorphic association (:as => :contactable ). However, contactable is actually a base class called ContactInformation which uses STI to contain contactable information of all types.
At one point I decided that having 4 extra fields for addresses was cluttering up the STI relationship but I still wanted to keep it. My solution was to serialize all those fields into the "info" field of ContactInformation. Right now, phone numbers only have "number" as a field that is serialized and stored into "info" but if I ever want to seperate it out into "area code" "extension" etc the implementation will be simple.
This leads to the problem. On my registration form I was using label / info for my phone_number fields instead of label / number. I had edited my edit form but not my new form (yes i know they should be the same one but I have a special ajax form for editing).
Here is the code for ContactInformation / PhoneNumber / Address
class ContactInformation < ActiveRecord::Base
attr_accessible :contactable_id, :contactable_type, :info, :label, :type
belongs_to :contactable, :polymorphic => true
end
class PhoneNumber < ContactInformation
attr_accessible :number
stash :number, in: :info
#----------------------------------Validations--Start-------------------------
validates :number, presence: true
#----------------------------------Validations--End---------------------------
end
class Address < ContactInformation
attr_accessible :street_address, :city, :state, :postal
stash :street_address, :city, :state, :postal, in: :info
#----------------------------------Validations--Start-------------------------
validates :street_address, :city, :state, :postal, presence: true
#----------------------------------Validations--End---------------------------
end

Related

has_one, reject_if, and accept_nested_attributes_for still triggers validation

I'm trying to provide a place to set a single service login for an account, yet not require that the account owner enter the service login credentials every time the rest of the record is updated.
My understanding is that the :reject_if option on accepts_nested_attributes_for is the way to have the nested hash values ignored. Yet, in Rails 4.1, I'm getting a "password can't be blank".
I've traced through the nested_attributes code and it seems to properly ignore the values, yet nothing I do to avoid the update works. I've even deleted the web_service_user_attributes hash from the params passed to update, so I'm wondering if there is something else going on.
Am I understanding :reject_if correctly for a has_one association?
Parent model code:
class Account
has_one :web_service_user
accepts_nested_attributes_for :web_service_user, :allow_destroy => true, :reject_if => :password_not_specified, :update_only => true
def password_not_specified(attributes)
attributes[:password].blank?
end
end
Child model code:
class WebServiceUser
devise :database_authenticatable
belongs_to :account
validates_uniqueness_of :username
validates_presence_of :password, if: Proc.new{|wsu| !username.blank? }
end
Controller code:
def update
respond_to do |format|
if #licensee.update(account_params)
#etc...
end
private
def account_params
params.require(:account).permit(:name, :area_of_business, :address1, :address2, :city, :state_code, :zip, :website_url, :web_service_user_attributes => [:id, :username, :password, :_destroy])
end
Ok, it appears that my primary goof was trying to validate the presence of :password. I really wanted to validate the length of the password if it existed.
class WebServiceUser
devise :database_authenticatable
belongs_to :account
validates_uniqueness_of :username
validates_length_of :password, :minimum => 14, if: Proc.new { |u| !u.password.nil? }
end

Updating attributes of a nested model

I have a nested model where a "Vendor" contains fields from the "User" model.
**Vendor.rb**
has_one :user, as: :profile, dependent: :destroy
accepts_nested_attributes_for :user, allow_destroy: true
**User.rb**
belongs_to :profile, polymorphic: true
The address and password fields reside in the user model. When I try to update the Vendor model without explicitly specifying the password, the password digest fields get set to nil. The same is true for the address fields and all the other fields in the user model.
Here's the controller:
def update
#vendor = Vendor.friendly.find(params[:id])
if #vendor.update_attributes(vendor_params)
flash[:success] = "Profile updated"
redirect_to(#vendor)
else
render 'edit'
end
end
def vendor_params
params.require(:vendor).permit(:company, :website,
:user_attributes => [:phone_number, :email, :email_confirmation, :password, :password_confirmation, :address,
:street_num, :street, :city, :state, :zip, :country, :latitude, :longitude, :password_flag])
end
How can I fix this? Specifically, what modifications do I need to make such that the application only updates the fields I specify on the form?
It looks like you have the modify the model as such:
accepts_nested_attributes_for :user, allow_destroy: true, update_only: true
Adding the update_only: true prevents it from creating a new instance of user

Ruby on Rails through Heroku object associations :belongs_to :has_many

Real newb question here: I've got courses
class Course < ActiveRecord::Base
attr_accessible :name, :number
has_many :posts
validates :name, presence: true
validates :number, presence: true
validates :number, :format => { :with => /\A\d\d[-]?\d\d\d\z/}
end
and I've got posts
class Post < ActiveRecord::Base
attr_accessible :comments, :course_id, :difficulty, :enjoyability, :hours, :professor, :ranking, :semester, :usefulness
belongs_to :course
end
Almost everything I have was auto-generated by Rails. There are a couple of things I try to do that I can't get to work:
When I "show" a course, I want to show each post associated with that course. However, everything I've tried has given me an error.
After even entering one post into the database (heroku forced me to use PostgreSQL) the index form no longer renders.
I'm almost positive I'm missing something with my associations between them. Does anybody have any ideas as to what I'm doing wrong?
You may get all posts through Course instance:
#course = Course.find(params[:id])
#posts = #course.posts

Rails 3 association error: undefined method

I've been puzzling over this for quite some time now and can't figure it out.
I've got 2 models:
class Vehicle < ActiveRecord::Base
attr_accessible :year, :capacity,
:size, :body, :model_id, :maker_id, :parameters_attributes
validates :year, numericality: { greater_than: 1900 }
validates :year, :capacity, :size, :body, presence: true
belongs_to :model
belongs_to :maker
has_many :parameters
accepts_nested_attributes_for :parameters
end
and
class Parameter < ActiveRecord::Base
attr_accessible :tag, :value
validates :tag, :value, presence: true
belongs_to :vehicle
end
in new vehicle view i've got:
= form_for [:admin, #vehicle], html: { multipart: true } do |f|
=# some other stuff in between
= f.text_field :value, size: 4
I get this error
undefined method `value'
Just can't seem to get it working. Help, anyone?
EDIT
routes.rb
resources :vehicles
resources :parameters
resources :makers do
resources :models
end
If you are using nested form, you should have something like
f.fields_for :parameters do |parameter|
and than:
parameter.text_field :value, size: 4
Also, remember to create the some parameters in the controller, for example:
def new
#vehicle = Vehicle.new
2.times { #vehicle.parameters.build } #it will create 2 parameters
...
end
f refers to #vehicle, it seems only Parameter bears this field. That's why it fails.
Sidenotes:
In Vehicle you have accepts_nested_attributes_for :parameters but you don't have parameters_attributes in the attr_accessible, can't be good.
If you want to call the relationship in the form consider using fields_for
Ok, I've made a mess of things.
Firstly I've been trying to
def new
#vehicle = #vehicle.parameters.build
end
hence the error undefined method. After a while I got to the correct syntax, which is the one gabrielhilal added after a while.
def new
#vehicle = Vehicle.new
#vehicle.parameters.build
end
No matter ;) Still had problems, because after clicking "create" he wouldn't add records in the database. Turned out that I've set the validates presence: true for tag, but didn't assign any value to it. After fixing that, it worked like a charm. Thanks a lot for all the help.
On to the next puzzle.

How can I properly configure rails 3 nested attributes

I have 2 models. Member and Survey
member.rb as follows
Class Member < ActiveRecord::Base
has_one :survey, :dependent => :destroy
accepts_nested_attributes_for :survey
attr_accessible :fname,:lname, :address, :city, :state, :zip, :email, :phone, :phone_alt, :e_contact, :e_contact_phone, :physician, :physician_phone, :chiropractor, :chiropractor_phone, :password, :password_confirmation, :remember_me, :survey_attributes
end
survey.rb as follows
Class Survey < ActiveRecord::base
belongs_to :member
end
however, whenever I try to create the member with the survey attributes I receive
ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes: surveys
I am testing this via the console.
With a has_one association the accessible call should read:
attr_accessible :survey_attributes
The params you're posting need to be nested, like so:
params = { :member => { :name => 'Jack', :survey_attributes => { :attribute => 'value' } } }
In the form make sure that you're building the nested relationship correctly, ie. you must use:
= form_for #member do |f|
...
= f.fields_for :survey do |s|
...
If you have those things setup like so it should work. If this isn't catching your error then please show a log of what you're trying in the console and isn't working.
See #accepts_nested_attributes_for in the Rails API for more info.

Resources