been banging my head on the table over this one. I have another nested form but this one is driving me crazy.
The error is:
TypeError in CompaniesController#create
no implicit conversion of Symbol into Integer
#company = Company.new(company_params)
The controller:
class CompaniesController < ApplicationController
layout 'welcome'
def new
#company = Company.new
end
def create
#company = Company.new(company_params)
if #company.save
flash[:notice] = "New company created successful."
redirect_to admin_accounts_path
else
flash.now[:alert] = "Creation failed, please try again"
render :new
end
end
private
def company_params
params.require(:company).permit(:name, :location, :users_attributes => [:email, :password])
end
end
On the new.html.erb:
<%= render partial: 'form', locals: { company: #company, users_attributes: :users_attributes } %>
This code looks exactly like another nested setup I have, but it works :p
I had read that sometimes changing the params from => to just having a semicolon works, but replacing the user_attributes => with a user_attributes: didn't change anything.
EDIT: form.html.erb
<%= form_for company, url: companies_path do |f| %>
<div class="col-12">
<div class="row">
<div class="col p-0 mr-3">
<div class="form-group">
Company <%= f.label :name %>
<%= f.text_field :name, :placeholder => 'Company name', class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :location %>
<%= f.text_field :location, :placeholder => 'Location', class: 'form-control' %>
</div>
</div>
<div class="col p-0">
<%= f.fields_for users_attributes do |user_f| %>
<div class="form-group">
<%= user_f.label :email %>
<%= user_f.text_field :email, :placeholder => 'Your Email Address', class: 'form-control' %>
</div>
<div class="form-group">
<%= user_f.label :password %>
<%= user_f.password_field :password, :placeholder => 'Password', class: 'form-control' %>
</div>
<% end %>
</div>
<div class="col-12 p-0">
<%= f.submit "Sign-Up", :class => 'btn btn-primary btn-block btn-lg' %>
</div>
</div>
</div>
<% end %>
Use users instead of users_attributes on the form.
Don't forget to define accepts_nested_attributes_for :users in model Company
## new.html.erb
<%= render partial: 'form', locals: { company: #company, users_attributes: :users } %>
I wonder why you didn't put :users into the form directly
I am new to develop rails project, I have a nested form for submitting Event and Ticket by using gem 'cocoon'.And the form have some check_boxes .
When you submit new , it does not matter, but in edit, you can not put checked in my checkboxes.
How do i do that given my code below?
My error
undefined method `include?' for nil:NilClass
<%= f.check_box :payment_type, { multiple: true ,checked:f.object.payment_type.include?(pay), include_hidden: false }, pay %>
<%= f.label :payment_type, pay, :value => i %>
My Model
class Event < ActiveRecord::Base
has_many :tickets, inverse_of: :event
accepts_nested_attributes_for :tickets, allow_destroy: true
class Ticket < ActiveRecord::Base
belongs_to :event
My Controller
class EventsController < ApplicationController
before_action :set_event, only: [:show, :edit, :update, :destroy]
def new
#event = Event.new
end
def create
#event = Event.new(event_params)
if #event.save
flash[:notice] = 'wow'
redirect_to #event
else
flash[:notice] = 'oh..'
render 'new'
end
end
def edit
end
def update
if #event.update(event_params)
redirect_to #event
else
render 'edit'
end
end
My form
<div class="nested-fields">
<h3>tickets</h3>
<div class="row formsection text-center">
<div class="col-md-3">
<span class="label-title">fee</span>
</div>
<div class="col-md-9">
<div class='input-group'>
<%= f.text_field :fee, :placeholder => "fee" , :class => "form-control" %>
</div>
</div>
</div>
<div class="row formsection text-center">
<div class="col-md-3">
<span class="label-title">payment</span>
</div>
<div class="col-md-9">
<%= f.hidden_field :id %>
<% payments = { 'paypal' => 1, 'credit card' => 2 } %>
<% payments.each do |pay,i| %>
<%= f.check_box :payment_type, { multiple: true ,checked: f.object.payment_type.include?(i), include_hidden: false }, i %>
<%= f.label :payment_type, pay, :value => i %>
<br>
<% end %>
</div>
</div>
<%= link_to_remove_association 'remove this', f %>
</div>
Not sure why it works on new, but if payment_type is not yet set, and so is nil, this will give the error you showed.
So instead write something like:
<%- checked_value = f.object.payment_type.present? && f.object.payment_type.include?(i) %>
<%= f.check_box :payment_type, { multiple: true ,checked: checked_value, include_hidden: false }, i %>
So this may be somewhat related to my question that I asked earlier, so here is a link to it, just in case.
So, currently I'm getting the error undefined method 'location' for #<Block:0x6503478>.
I've already gotten the has_one relation for cue working, but what seems to be the problem is the has_many relations with block_block and block_character.
The parameters being passed are:
{"utf8"=>"✓",
"authenticity_token"=>"blahblahblah",
"block"=>{"block_code"=>"1",
"block_duration"=>"",
"cue"=>"no",
"cue_attributes"=>{"cue_code"=>"",
"cue_type_code"=>"",
"cue_description"=>"",
"cue_method_code"=>""},
"location_code"=>"1",
"scene_code"=>"1",
"block_description"=>"",
"block_block"=>{"block_block_code"=>"",
"primary_block_code"=>"",
"secondary_block_code"=>"",
"block_block_start"=>""},
"block_character"=>{"block_character_code"=>"",
"character_code"=>"",
"block_code"=>"",
"character_action"=>"",
"character_motivation"=>""}},
"blockblock"=>{"block"=>"no"},
"blockblockdirect"=>{"blockdirect"=>"before"},
"blockchar"=>{"character"=>"no"},
"commit"=>"Create Block"}
Here is my form for block (views/block/_form.html.erb):
<%= form_for(#block) do |f| %>
<% if #block.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#block.errors.count, "error") %> prohibited this block from being saved:</h2>
<ul>
<% #block.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field hidden">
<%= f.label :block_code, class: "hidden" %><br>
<%= f.text_field :block_code, class: "form-control hidden" %>
</div>
<div class="field">
<%= f.label :block_duration %><br>
<div class="input-group">
<%= f.number_field :block_duration, class: 'text_field form-control', :step => 'any' %>
<div class="input-group-addon">seconds</div>
</div>
</div>
<div class="field">
<%= label "cue", "Does this block have a cue associated with it?" %>
<!-- Add whether it is specific/generic cue -->
<%= radio_button_tag "block[cue]", "yes", false %> Yes
<%= radio_button_tag "block[cue]", "no", true %> No
<div class="field" id="cue_fields" style="display:none;">
<%= f.fields_for :cue, #block.build_cue do |ff| %>
<div class="field hidden">
<%= ff.label :cue_code, class: "hidden" %><br>
<%= ff.text_field :cue_code, class: "hidden" %>
</div>
<div class="field">
<%= ff.label "Cue Type" %><br>
<%= ff.collection_select(:cue_type_code, CueType.all, :cue_type_code, :cue_type_name, {prompt: "Select a cue type..."}, {class: "form-control"}) %>
</div>
<div class="field">
<%= ff.label "Cue Description" %><br>
<%= ff.text_area :cue_description, class: "form-control" %>
</div>
<div class="field">
<%= ff.label "Cue Method" %><br>
<%= ff.collection_select( :cue_method_code, CueMethod.all, :cue_method_code, :cue_method_name, {prompt: "Select a cue method..."}, {class: "form-control"}) %>
</div>
<% end %>
</div>
</div>
<div class="field">
<%= f.label "Location" %><br>
<%= collection_select :block, :location_code, Location.all, :location_code, :location_name, {prompt: "Select a location..."}, {class: "form-control", required: true} %>
</div>
<div class="field">
<%= f.label "Scene" %><br>
<%= f.collection_select :scene_code, Scene.all, :scene_code, :actAndScene, {prompt: "Select a scene..."}, {class: "form-control", required: true} %>
</div>
<div class="field">
<%= f.label "Block Description" %><br>
<%= f.text_area :block_description, class: "form-control" %>
</div>
<!-- This needs work -->
<div class="field">
<%= label "blockblock", "Is this block associated with any other blocks?" %>
<%= radio_button_tag "blockblock[block]", "yes", false %> Yes
<%= radio_button_tag "blockblock[block]", "no", true %> No
<div class="field" id="blockblock_fields" style="display:none;">
<ol>
<li>
<%= label "blockdirect", "Does this block come directly before or after another block?" %>
<%= radio_button_tag "blockblockdirect[blockdirect]", "before", true %> Before
<%= radio_button_tag "blockblockdirect[blockdirect]", "after", false %> After
<%= f.fields_for :block_block do |gg| %>
<div class="field hidden">
<%= gg.label :block_block_code, class: 'hidden' %><br>
<%= gg.text_field :block_block_code, class: 'hidden' %>
</div>
<div class="field" id="blockblock_after_fields" style="display:none;">
<%= gg.label "Primary Block Code" %><br>
<%= gg.text_field :primary_block_code, class: 'form-control' %>
</div>
<div class="field" id="blockblock_before_fields">
<%= gg.label "Secondary Block Code" %><br>
<%= gg.text_field :secondary_block_code, class: 'form-control' %>
</div>
<div class="field">
<%= gg.label "Block Start" %><br>
<p><i>This field indicates the amount of time after the first block starts that the second block should begin, i.e. if you type "1" here, then the second block will start 1 second after the first block starts</i></p>
<div class="input-group">
<%= gg.number_field :block_block_start, class: 'text_field form-control', :step => 'any' %>
<div class="input-group-addon">seconds</div>
</div>
</div>
<% end %>
</li>
</ol>
</div>
</div>
<!-- This needs work -->
<div class="field">
<%= label "character", "Are any characters associated with this block?" %>
<%= radio_button_tag "blockchar[character]", "yes", false %> Yes
<%= radio_button_tag "blockchar[character]", "no", true %> No
<div class="field" id="character_fields" style="display:none;">
<ol>
<%= f.fields_for :block_character do |hh| %>
<li>
<div class="field hidden">
<%= hh.label :block_character_code, class: 'hidden' %><br>
<%= hh.text_field :block_character_code, class: 'hidden' %>
</div>
<div class="field">
<%= hh.label "Character" %><br>
<%= hh.collection_select :character_code, Character.all, :character_code, :character_name, {prompt: "Select a character..."}, {class: "form-control"} %>
</div>
<div class="field hidden">
<%= hh.label :block_code, class: 'hidden' %><br>
<%= hh.text_field :block_code, class: 'hidden' %>
</div>
<div class="field">
<%= hh.label :character_action %><br>
<%= hh.text_field :character_action, class: 'form-control' %>
</div>
<div class="field">
<%= hh.label :character_motivation %><br>
<%= hh.text_area :character_motivation, class: 'form-control' %>
</div>
</li>
<% end %>
</ol>
</div>
</div>
<div class="actions">
<%= f.submit "Create Block", class: "btn btn-primary" %>
</div>
<% end %>
Additionally, here are the models associated with block, block_character, and block_block, respectively:
class Block < ActiveRecord::Base
validates_presence_of :location
validates_presence_of :scene
has_one :cue
has_many :block_blocks
has_many :block_characters
accepts_nested_attributes_for :cue, allow_destroy: true
accepts_nested_attributes_for :block_blocks, allow_destroy: true
accepts_nested_attributes_for :block_characters, allow_destroy: true
attr_accessor :block_blocks
attr_accessor :block_characters
end
class BlockBlock < ActiveRecord::Base
belongs_to :block
end
class BlockCharacter < ActiveRecord::Base
belongs_to :block
end
Here is the controller for block:
class BlocksController < ApplicationController
before_action :set_block, only: [:show, :edit, :update, :destroy]
# GET /blocks
# GET /blocks.json
def index
#blocks = Block.all
end
# GET /blocks/1
# GET /blocks/1.json
def show
end
# GET /blocks/new
def new
#block = Block.new
# Set block code as next integer after max block code.
#block.block_code = (Block.maximum(:block_code).to_i.next).to_s(2)
end
# GET /blocks/1/edit
def edit
end
# POST /blocks
# POST /blocks.json
def create
#block = Block.new(block_params)
respond_to do |format|
if #block.save
format.html { redirect_to #block, notice: 'Block was successfully created.' }
format.json { render :show, status: :created, location: #block }
else
format.html { render :new }
format.json { render json: #block.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /blocks/1
# PATCH/PUT /blocks/1.json
def update
respond_to do |format|
if #block.update(block_params)
format.html { redirect_to #block, notice: 'Block was successfully updated.' }
format.json { render :show, status: :ok, location: #block }
else
format.html { render :edit }
format.json { render json: #block.errors, status: :unprocessable_entity }
end
end
end
# DELETE /blocks/1
# DELETE /blocks/1.json
def destroy
#block.destroy
respond_to do |format|
format.html { redirect_to blocks_url, notice: 'Block was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_block
#block = Block.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def block_params
params.require(:block).permit(:block_code, :block_duration, :cue_code, :location_code, :scene_code, :block_description, :cue_attributes => [:id, :cue_code, :cue_type_code, :cue_description, :cue_method_code], :block_block_attributes => [:id, :block_block_code, :primary_block_code, :secondary_block_code, :block_block_start], :block_character_attributes => [:id, :block_character_code, :character_code, :block_code, :character_action, :character_motivation])
end
end
And finally, the migrations I added for id and foreign_key for both block_block and block_character:
class AddBelongsToToBlockBlocks < ActiveRecord::Migration
def change
add_reference :block_blocks, :block, index: true
add_foreign_key :block_blocks, :blocks
end
end
class AddBelongsToToBlockCharacters < ActiveRecord::Migration
def change
add_reference :block_characters, :block, index: true
add_foreign_key :block_characters, :blocks
end
end
Honestly, thank you all so much for your help through this, I am by no means an advanced Rails user and this has all been amazingly helpful. Please let me know if you need any more information!
UPDATE 1
So I changed the following in block.rb (the model file), as suggested by Vijay (thanks so much!!!):
class Block < ActiveRecord::Base
validates_presence_of :location_code
validates_presence_of :scene_code
has_one :cue
has_many :block_blocks
has_many :block_characters
accepts_nested_attributes_for :cue, allow_destroy: true
accepts_nested_attributes_for :block_blocks, allow_destroy: true
accepts_nested_attributes_for :block_characters, allow_destroy: true
attr_accessor :block_blocks
attr_accessor :block_characters
end
At this point, the block saves (and appears in the index view), but the block_block and block_character do not do so. There is no associated error however...
UPDATE 2
This is currently what the params submitted look like:
Which is odd because it says that cue, block_block, and block_character are unpermitted parameters, even though, in the controller they are:
def block_params
params.require(:block).permit(:block_code, :block_duration, :cue_code, :location_code, :scene_code, :block_description, :cue_attributes => [:id, :cue_code, :cue_type_code, :cue_description, :cue_method_code], :block_block_attributes => [:id, :block_block_code, :primary_block_code, :secondary_block_code, :block_block_start], :block_character_attributes => [:id, :block_character_code, :character_code, :block_code, :character_action, :character_motivation])
end
Are you triggering the error in the validation?
validates_presence_of :location
From your code it looks like it should be
validates_presence_of :location_code
Not sure why you've added these in Rails 4
attr_accessor :block_blocks
attr_accessor :block_characters
Try removing them and see if they are interfering with the controller (I'm guessing, but happy to play if you put up a jsfiddle)
My repo: https://github.com/Gtar69/artstore_hw2
I want to implement upload more than 1 photo in certain product.
The basic idea is that administrator enter edit page of the product and can "upload new photos" for certain product.Im struggling in "how to create a photo object in edit page and add this photo object to product. !!! I can not successfully create a photo object in edit page .....
Very Thanks
in view/admin/products/edit.html.erb
<h2> 編輯 <%= #product.title %> </h2>
<%= simple_form_for [:admin, #product ] , :html => { :class => "form form-horizontal" } do |f| %>
<div class="form-group">
<div class="col-sm-10">
<%= f.input :title %>
</div>
</div>
<div class="form-group">
<div class="col-sm-10">
<%= f.input :description, :as => :text %>
</div>
</div>
<div class="form-group">
<div class="col-sm-1">
<%= f.input :quantity %>
</div>
</div>
<div class="form-group">
<div class="col-sm-1">
<%= f.input :price %>
</div>
</div>
<!-- 20140623 upload more than one photo feature added -->
<div>
<%= simple_form_for [:admin, #product, #product.photos.build] do |f| %>
<%= f.input :image , :as => :file %>
<div class="form-group">
<%= f.submit "upload new photos", :class => "btn btn-default" , :disable_with => 'Submiting...' %>
</div>
<%end%>
</div>
<div class="form-group">
<%= f.submit "Submit", :class => "btn btn-default" , :disable_with => 'Submiting...' %>
</div>
<% end %>
in controllers/admin/products_controller.rb
def edit
#product = Product.find(params[:id])
##photo = #product.photos.build
##product.add_photo_to_product(#photo)
end
in controllers/admin/photos_controller.rb
def create
#binding.pry
#product = Product.find(params[:product_id])
#photo = #product.photos.create(photo_params)
#product.add_photo_to_product(#photo)
redirect_to admin_products_path
end
private
def photo_params
params.require(:photo).permit(:image)
end
in model/product.rb
class Product < ActiveRecord::Base
has_many :photos
accepts_nested_attributes_for :photos
validates :title , :presence => true
validates :quantity , :presence => true
def default_photo
photos.first
end
def add_photo_to_product(photo)
photos << photo
end
end
in photos.rb
class Photo < ActiveRecord::Base
belongs_to :product
mount_uploader :image, ImageUploader
end
I'm new in rails and currently trying to create an app but I can't seem to make it work. Here's my setup in model.
class User < ActiveRecord::Base
has_one :doctor, dependent: :destroy
accepts_nested_attributes :doctor
end
class Doctor < ActiveRecord::Base
belongs_to :user, :dependent => :destroy
end
In my users_controller, here's my code:
class UsersController < ApplicationController
def show
#user = current_user
# render text: #user.inspect
end
def new
#user = User.new
#user.build_doctor`
end
def create
# binding.pry
#user = User.new(user_params)
if #user.save
sign_in #user
redirect_to dashboard_path
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:role, :lastname, :firstname, :middlename, :email, :password, :password_confirmation, :doctor_attributes => [:institution, :license_number])
end
end
And my view:
<ul id="cbp-bislideshow" class="cbp-bislideshow">
<li>
<%= image_tag "blur1.jpg" %>
</li>
<li>
<%= image_tag "blur2.jpg" %>
</li>
</ul>
<% provide(:title, 'Sign Up') %>
<%= form_for(#user) do |f| %>
<div class="sign-up-wrapper divided-wrapper cf">
<div class="left-section">
<h3 class="section-title">JOIN US AND LET'S CHANGE THINGS</h3>
<div class="row">
<div class="w49 pull-left">
<%= f.text_field :firstname, class: "input-text personal ", placeholder: 'FIRSTNAME' %>
</div>
<div class="w49 pull-right">
<%= f.text_field :lastname, class: "input-text personal", placeholder: 'LASTNAME' %>
</div>
<%= f.hidden_field :role, value: :doctor %>
</div>
<div class="row">
<%# f.text_field :specialization, class: "input-text personal ", placeholder: 'SPECIALIZATION' %>
</div>
<%= f.fields_for :doctors do |p| %>
<div class="row">
<%= p.text_field :institution, class: "input-text personal ", placeholder: 'INSTITUTION' %>
</div>
<div class="row">
<%= p.text_field :license_number, class: "input-text personal ", placeholder: 'LICENSE NUMBER' %>
</div>
<% end %>
<span class="remind bottom-message"> ONCE INSIDE DON'T FORGET TO UPDATE YOUR PROFILE WITH MORE DETAILS </span>
</div>
<div class="right-section">
<h3 class="section-title"></h3>
<div class="row">
<%= f.text_field :email, class: "input-text personal ", placeholder: 'EMAIL' %>
</div>
<div class="row">
<%= f.password_field :password, class: "input-text personal ", placeholder: 'PASSWORD' %>
</div>
<div class="row">
<%= f.password_field :password_confirmation, class: "input-text personal ", placeholder: 'CONFIRM PASSWORD' %>
</div>
<div class="row cf">
<%= f.submit class: 'btn-join btn', value: 'JOIN NOW' %>
</div>
<div class="row">
SIGN UP WITH FACEBOOK / TWITTER ACCOUNT?
</div>
</div>
</div>
<% end %>
Everytimie I execute these pieces, only the user model gets populated but not the doctors table? Is there something wrong on my code?
EDIT
Changed doctors_attributes to doctor_attributes
changed #user.doctor.build`to #user.build_doctor
In the logs. I saw this error ---> Unpermitted parameters: doctors
So in theory, I think we know what's the problem, but I don't know how to fix this in the strong_parameters. Haven't tried a strong_parameter with accepted_nested_attributes_for in rails yet and this is my first time. Any solution?
In the fields_for, replace :doctors with :doctor. Remember that you're doing a 1 to 1 relationship.
In your user_params model, the attribute doctors_attributes should be doctor_attributes since it's a has_one relationship. If it was a has_many relationship, it would be doctors_attributes. The part before _attributes would be whatever the association is named.
Another note: If you want to be able to update the doctor from the user form, you should also include the id in the doctor_attributes array. Though now that I think of it, it might only be a requirement on has_many nested associations. I've never tried doing a has_one without including the id.