Undefined method 'build' in rails 3 - ruby-on-rails-3

I am getting a "NoMethodError in ProjectsController#create" with the following code:
def create
#project = current_user.project.build(params[:project])
if #project.save
flash[:success] = "Project created!"
redirect_to root_url
end
end
I have tried using #project = current_user.project.create(params[:project]) as well, but I get the same error, albeit for .create.
My Project model looks like this:
class Project < ActiveRecord::Base
attr_accessible :title,
:sub_title,
:desc,
:category
validates :user_id, presence: true
validates :title, presence: true, length: { maximum: 35 }
validates :category, presence: true
belongs_to :user
...
end
and my User model looks like this:
class User < ActiveRecord::Base
attr_accessible :name,
:surname,
:email,
:email_confirmation,
:password,
:password_confirmation
has_secure_password
has_one :project
...
end
From what I can tell, this should create a new Project with an association to the user.id and project.user_id. Any ideas why I get the error instead of successful creation?

For has_one associations you want:
#project = current_user.build_project(params[:project])
The same pattern is used for create:
#project = current_user.create_project(params[:project])
If you look at the has_one documentation they list the methods that get created when you declare the association.

Related

Couldn't find <Model> with ID=14 for Property with ID=1

when update, i got error like this.
Couldn't find PropertyAcceptanceCriterion with ID=14 for Property with ID=1
this error occur when off the checkbox, and update(save).
what should i do next,
model definition is
class PropertyAcceptance < ActiveRecord::Base
belongs_to :property
belongs_to :property_acceptance_criterion
end
class PropertyAcceptanceCriterion < ActiveRecord::Base
attr_accessible :name
has_many :property_acceptances, dependent: :destroy
has_many :properties, through: :property_acceptances
end
class Property < ActiveRecord::Base
attr_accessible :rent
attr_accessible :room_no
attr_accessible :property_acceptance_criterions_attributes
attr_accessible :property_acceptance_criterion_ids
has_many :property_acceptances, dependent: :destroy
has_many :property_acceptance_criterions, through: :property_acceptances
accepts_nested_attributes_for :property_acceptance_criterions, reject_if: lambda { |a| a[:name].blank? }
end
view definition is
= simple_nested_form_for #property do |f|
= f.input :room_no, input_html: {class: 'span2'}
= f.input :rent, input_html: {class: 'span2'}
= f.association :property_acceptance_criterions, as: :check_boxes
= f.simple_fields_for :property_acceptance_criterions do |c|
= c.input :name, label: "add for #{t('activerecord.attributes.property.property_acceptance_criterions')}" if c.object.new_record?
controller definition is
class Insurance::PropertiesController < Insurance::InsuranceController
before_filter :load_property, only: [:edit, :update]
before_filter :new_property, only: [:new, :create]
def new
#property.property_acceptance_criterions.build
end
def create
#property.attributes = params[:property]
if #property.save
redirect_to #property, success: t('activerecord.flash.property.actions.create.success')
else
render :new
end
end
def edit
#property.property_acceptance_criterions.build
end
def update
if #property.update_attributes(params[:property]) # ← error occur
redirect_to #property, success: t('activerecord.flash.property.actions.update.success')
else
render :edit
end
end
private
def load_property
#property = Property.find(params[:id])
end
def new_property
#property = Property.new
end
end
error is
Couldn't find PropertyAcceptanceCriterion with ID=14 for Property with ID=1
params is
{"utf8"=>"✓",
"_method"=>"put",
"authenticity_token"=>"+Zx7l7mAbX12PSO873x5NDxNOIeEe6bEDEdVnys+a98=",
"property"=>{
"room_no"=>"000",
"rent"=>"80000",
"property_acceptance_criterion_ids"=>["13", "25", ""],
"property_acceptance_criterions_attributes"=>{
"0"=>{"id"=>"13"}, "1"=>{"id"=>"14"}, "2"=>{"id"=>"25"}, "3"=>{"name"=>""}
},
"commit"=>"update",
"id"=>"1"}

How to use "accepts_nested_attributes_for" in rails 3?

I'm following the docs and toying with simple_form, formtastic, and nested_form gems with no success. This very simple example yields empty for for me:
resort.rb
class Resort < ActiveRecord::Base
attr_accessible :address, :description, :latitude, :longitude, :name, :phone, :second_name,
:resort_type_id, :infrastructure_attributes
validates_presence_of :name, :address, :phone, :description
has_many :infrastructures
belongs_to :resort_type
accepts_nested_attributes_for :infrastructures
end
infrastructure.rb
class Infrastructure < ActiveRecord::Base
attr_accessible :name, :description, :infrastructure_type_id, :resort_id
belongs_to :resort
belongs_to :infrastructure_type
end
form view
= form_for #resort do |f|
= f.fields_for :infrastructures do |i|
= i.text_field :name
Seems I missed something obvious but can't figure out what exactly is wrong with the code.
If I may ask, in your controller action did you build the appropriate code for your infrastructure. Something like
3.times { #resort = #resort.infrastrucures.build }
To my knowledge you need something like this for your form before it can build the proper nested form content

Rails easy nested form

Hello i have problem with nested form.. im looking an hour to that and dont know what i forget ..
models/trainer.rb
class Trainer < ActiveRecord::Base
attr_accessible :telephone, :user_attributes
has_one :user
accepts_nested_attributes_for :user
end
models/user.rb
class User < ActiveRecord::Base
belongs_to :trainer
attr_accessible :email, :image_url, :name, :password_hash, :password_salt, ...
attr_accessible :password, :password_confirmation
attr_accessor :password
before_save :encrypt_password
<+ validations ...>
controllers/trainers_controller.rb
def new
#trainer = Trainer.new
#trainer.build_user
respond_to do |format|
format.html # new.html.erb
format.json { render json: #trainer }
end
end
and i can display new trainer form view (i addedd all user columns as nested)
but when i hit CREATE i get
Can't mass-assign protected attributes: user
whats wrong ? thank you
edit: my db schema looks like
[users]
id
trainer_id
name
surname
[trainers]
telephone
Here i uploaded my simplify simple app if anyone was interested :)
https://github.com/ScottHiscock/NestedForm
Ref accepts_nested_attributes_for
Defines an attributes writer for the specified association(s).
If you are using attr_protected or attr_accessible, then you will need to add
the attribute writer to the allowed list.
So I think you have to do the following:
class Trainer < ActiveRecord::Base
attr_accessible :telephone, :user_attributes
Also add user to attr_accessible list of trainer.rb model as follows
attr_accessible :telephone, :user_attributes
or try this
attr_accessible :telephone, :user
the mistake was in the view, i had
<%= f.fields_for :users do |u| %>
but correct is
<%= f.fields_for :user do |u| %>
:-)

Rails 3 UnknownAttributeError For Nested Model

I've been getting the UnkownAttributeError for no particular reason, my models seem to be setup correctly...
School.rb
class School < ActiveRecord::Base
attr_protected :id, :created_at, :updated_at
#relationships
has_many :users
accepts_nested_attributes_for :users
end
My School model used to have the following, but it produced a MassAssignmentSecurity error for the user fields:
attr_accessible :country, :name, :state_or_province, :users_attributes
User.rb
class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation, :remember_me, :username, :instructor_id, :first_name, :last_name, :school_id
#relationships
belongs_to :school
end
new.html.haml
= simple_form_for #school do |f|
.well
= f.input :name, :as => :hidden
= f.input :country, :as => :hidden
= f.input :state_or_province, :as => :hidden
.well
= f.simple_fields_for #school.users.build do |user_form|
= user_form.input :first_name, :required => true
= user_form.input :last_name, :required => true
= user_form.input :username, :required => true
...
= f.button :submit, "Next"
Note: #school is being populated in my new action from session information gathered on the previous page, I'm making a multi-step form. The school data is perfectly valid, if I was to remove the user form it would have no trouble saving the school.
The specific error message I'm getting in my create action:
ActiveRecord::UnknownAttributeError in SchoolsController#create
unknown attribute: user
And the sent params looks a little like this:
{"school"=>{"name"=>"Elmwood Elementary", "country"=>"38",
"state_or_province"=>"448", "user"=>{"first_name"=>"joe",
"last_name"=>"asdas", "username"=>"asasdads",
"email"=>"asdasd#sdas.ca", "password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]"}}, "commit"=>"Next"}
Is this maybe a bug with either Devise or simple_form? I'm using Rails 3.2.3
Ok, so apparently I needed to provide the symbol :users - the name of the relationship as my first argument for it to work.

Rails 3 - trying to create polymorphic has_one association in console

Here's my code:
Models:
class Article < ActiveRecord::Base
attr_accessible :title, :author, :content, :imageable_attributes
has_one :image, as: :imageable, dependent: :destroy
accepts_nested_attributes_for :image, allow_destroy: true
validates_presence_of :title, :content, :author
end
class Image < ActiveRecord::Base
mount_uploader :image, ImageUploader
attr_accessible :image, :caption, :imageable_id, :imageable_type, :article_ref
validates_presence_of :image
belongs_to :imageable, :polymorphic => true
end
Here's what I've tried in console:
article = Article.create!(title: "test", content: "test", author: "test", image_attributes: {image: "test.jpg", caption: "test caption"})
This creates an Article without errors, but if I call:
article.image
I get:
=> nil
If I type in console:
article = Article.new(title: "test", content: "test", author: "test")
article.build_image(image: "test.jpg")
I get:
=> Validation failed: Image image can't be blank
Any help greatly appreciated, I'm very confused!
I believe it's necessary to supply the attachment itself, rather than just the path. As an example,
i = Image.new(
:image => File.join(Rails.root, "test.jpg")
)
i.image
# =>
but
i = Image.new(
:image => File.open(File.join(Rails.root, "test.jpg"))
)
i.image
# => /uploads/tmp/20120427-2155-1316-5181/test.jpg
It's not necessary to use File.open when saving using Multipart POST, though.