Type error on nested form - ruby-on-rails

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

Related

Contact name not showing name in DB

I'm a rookie, and looking to create a contact form, but when I check my submitted forms, it doesn't show the name. It just says name "" I'm using Ruby on Rails.
My html looks like;
Contact Us
<div class="col-md-4 col-md-offset-4">
<%= flash[:notice] %>
<div class="well">
<%= form_for #contact do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :comments %>
<%= f.text_area :comments, class: 'form-control' %>
</div>
<%= f.submit 'Submit', class: 'btn btn-default' %>
<% end %>
</div>
</div>
My controller code looks like;
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(contact_params)
if #contact.save
redirect_to new_contact_path, notice: "Message Sent."
else
redirect_to new_contact_path, notice: "Error Occured"
end
end
private
def contact_params
params.require(:contact).permit(:name, :email, :comments)
end
end
Probably your second text field is the problem, it's called :name twice...
change the second input and try it again
<%= f.text_field :name, class: 'form-control' %>
to
<%= f.text_field :email, class: 'form-control' %>

THE SUBMIT BUTTON

Udemy: Bootcamp course: section: 8 Lecture: 122: SAVING TO THE DATABSE: In the "Contact Us" page I filled in the info, Name: test1, Email: test1#example.com, Comments: test1, as a test, pressed submit, but the button do not submit the info and gives no error message. Where am I going wrong? Any expert advice? Here is my code:
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(contact_params)
if #contact.save
flash[:success] = 'Message sent.'
redirect_to new_contact_path
else
flash[:danger] = 'Error occured, message has not been sent.'
redirect_to new_contact_path
end
end
end
private
def contact_params
params.require(:contact).permit(:name, :email, :comments)
end
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="well"
<%= form_for #contact do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :comments %>
<%= f.text_area :comments, class: 'form-control' %>
</div>
<%= f.submit 'Submit', class: 'btn btn-default' %>
<% end %>
</div>
</div>
</div>
Im not a rails expert but you can try <%= form_for(#contact, :method => :get) do |f| %> that should get it to work.
In your contact.rb model type the following
class Contact < ActiveRecord::Base
end

Nested has_many attributes (Ruby on Rails) throwing errors

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)

Rails - how to send some information from one form to other controller

Firstly, I would like to describe what I am going to do. So, my application is set of tasks (eg. exercises depend on writing computer program) which user it available to send solutions through form and server will have compiled it and return results of process.
My problem is that I have model Solution which is presented below:
Solution(id: integer, exercise_id: integer, code: string, user_id: integer,
created_at: datetime, updated_at: datetime, language_id: integer)
and exercise_id, user_id, language_id are foreign keys and postgresql return error that it couldn't be null values...
The form which I use to send this information looks like below:
<fieldset style="add">
<legend>Send solution</legend>
<%= form_for [#user, #exercise, #solution], url: exercise_solutions_path, :html => { role: "form" } do |f| %>
<div class="form-group">
<%= f.label "Source code" %>
<br>
<%= f.text_area :code %>
</div>
<div class="form-group">
<%= f.label "Programming language" %>
<br>
<%= f.select(:language_id, available_lang) %>
</div>
<div class="form-group">
<%= f.submit "Send", :class => "btn btn-default" %>
</div>
<% end %>
</fieldset>
Frankly speaking I don't how to include more information such as user.id or exercise.id. Params look like:
#_params
{"utf8"=>"✓", "authenticity_token"=>"abwhTn3KrVneli0pCVccoWHyzlI7cRTFK5Wo7DdYRK+lL4GwZ8jUPqdzn8ZznCHsWTkfDAFS2RP6gTkWuk33iw==", "solution"=>{"code"=>"ds", "language_id"=>"C++"}, "commit"=>"Wyślij", "controller"=>"solutions", "action"=>"create", "exercise_id"=>"1"}
SolutionController
class SolutionsController < ApplicationController
def index
#solutions = Solution.last(20)
end
def new
#solution = Solution.new
end
def create
#solution = Solution.new(solution_params)
if #solution.save
redirect_to #solution
else
render :new
end
end
def edit
#solution = Solution.find(params[:id])
if #solution.update(solution_params)
redirect_to #solution
else
render :edit
end
end
def destroy
end
private
def solution_params
params.require(:solution).permit(:language_id, :code)
end
end
Edit:
<fieldset style="add">
<legend>Send solution</legend>
<%= form_for [#user, #exercise, #solution], url: exercise_solutions_path, :html => { role: "form" } do |f| %>
<div class="form-group">
<%= f.label "Source code" %>
<br>
<%= f.text_area :code %>
</div>
<div class="form-group">
<%= f.label "Programming language" %>
<br>
<%= f.select(:language_id, available_lang) %>
</div>
<div class="form-group">
<%= f.hidden_field :exercise_id, value: #exercise.id %>
<%= f.hidden_field :user_id, value: #user.id %>
<%= f.submit "Send", :class => "btn btn-default" %>
</div>
<% end %>
</fieldset>
You could 1) add hidden_fields in your form to set the missing attributes:
<div class="form-group">
<%= f.hidden_field :exercise_id, value: #exercise.id %>
<%= f.hidden_field :user_id, value: #user.id %>
<%= f.submit "Send", :class => "btn btn-default" %>
</div>
Make sure to add these attributes to the solution_params permitted parameters:
def solution_params
params.require(:solution).permit(:language_id, :code, :exercise_id, :user_id)
end
A better idea would be to manually set the exercise and user in the controller and leave your solution_params as is. That way you're not allowing the exercise and user to be set by mass assignment, which could be spoofed.
So instead do 2) in your controller:
def create
#solution = Solution.new(solution_params)
#solution.exercise_id = params[:exercise_id]
#solution.user_id = params[:user_id]
if #solution.save
redirect_to #solution
else
render :new
end
end
I'm assuming that :exercise_id and :user_id are in the URL. If not add them as hidden_fields as needed (but this time not on the form object):
<%= hidden_field_tag :user_id, #user.id %>
Also remember to actually select a language_id from the dropdown before you submit the form.

Rails - Right / Better way to to a belongs_to / has_many relationship

I am creating an application through which a user will be able to create an account. When they create an account, in the same form they will be able to create an organization that will then be tied to their user. Once that user has created their account (and an organization) other users will be able to create an account and use an "access code" to join that organization as well. Looking at the code may explain it better.
The reason i'm posting on SO is because i have a feeling there is a better / more efficient way to do it than what i am currently doing. I'm using nested_forms (maybe not correctly) and i don't think i'm doing the associations the right way because, for example, i haven't been able to get the edit form to fill out the organization fields.
I am using sorcery for the authentication as well.
users_controller.rb
def new
#user = User.new
end
def create
#user = User.new(user_params)
if params[:user][:organization][:name].blank?
flash.now[:error] = "You must specify an organization name."
render :new
else
if params[:user][:organization][:access_code].blank?
# create new organization
#access_code = "#{SecureRandom.urlsafe_base64(16)}#{Time.now.to_i}"
#organization = Organization.create(:name => params[:user][:organization][:name], :access_code => #access_code)
#user.organization_id = #organization.id
#user.is_admin = true
else
# try and add someone to an organization
#organization = Organization.find(:all, conditions: ["name = ? AND access_code = ?", params[:user][:organization][:name], params[:user][:organization][:access_code]])
if #organization.empty?
flash.now[:error] = "No organization has been found with that name and access code."
render :new
return
else
#user.organization_id = #organization.first.id
end
end
if #user.save
user = login(#user.email, params[:user][:password])
if user
flash[:success] = "Your account has been successfully created!"
redirect_to admin_dashboard_path
end
else
flash.now[:error] = "Something went wrong! Please try again."
render :new
end
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.is_admin?
if params[:user][:organization][:name].blank? && params[:user][:organization][:name] != #user.organization.name
params[:user][:organization][:name] = #user.organization.name
end
if params[:user][:organization][:access_code].blank? && params[:user][:organization][:access_code] != #user.organization.access_code
params[:user][:organization][:access_code] = #user.organization.access_code
end
#organization = Organization.find(params[:user][:organization_id])
#organization.name = params[:user][:organization][:name]
#organization.access_code = params[:user][:organization][:access_code]
#organization.save
end
if #user.update(user_params)
flash[:success] = "Your settings have been updated!"
redirect_to edit_admin_user_path(#user.id)
else
flash.now[:error] = "Something went wrong! Please try again."
render :edit
end
end
private
def user_params
params.require(:user).permit(:organization_id, :email, :password, :password_confirmation, :full_name, :remember_me, {:organization_attributes => [:name, :website, :description, :access_code]})
end
users.rb
class User < ActiveRecord::Base
authenticates_with_sorcery!
belongs_to :organization
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates_presence_of :full_name
validates_presence_of :email
validates_uniqueness_of :email, :on => :create
validates_format_of :email, :with => VALID_EMAIL_REGEX, :on => :create
validates_presence_of :password, :on => :create
validates_confirmation_of :password
end
organization.rb
class Organization < ActiveRecord::Base
authenticates_with_sorcery!
has_many :users, :dependent => :destroy
accepts_nested_attributes_for :users
validates_presence_of :name
end
new.html.erb
<% provide(:title, 'Create a User') %>
<h1>Create a User</h1>
<p>Use the form below to create an account.</p>
<%= nested_form_for([:admin, #user], html: {role: "form"}) do |f| %>
<%= render "shared/error_messages", obj: #user %>
<fieldset>
<legend>User Information</legend>
<div class="form-group">
<%= f.label :full_name, "Full Name" %>
<span class="help-block">How should others see you?</span>
<%= f.text_field :full_name, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :email %>
<span class="help-block">Your email address is used as your login.</span>
<%= f.text_field :email, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :password_confirmation, "Confirm Password" %>
<%= f.password_field :password_confirmation, class: "form-control" %>
</div>
</fieldset>
<%= f.fields_for :organization do |o| %>
<fieldset>
<legend>Associated Organization</legend>
<div class="form-group">
<%= o.label :name, "Organization Name" %>
<span class="help-block">This is the name of the organization you are a part of.</span>
<%= o.text_field :name, class: "form-control" %>
</div>
<div class="form-group">
<%= o.label :access_code, "Organization Access Code" %>
<span class="help-block">Leaving this field blank will setup a new organization.</span>
<%= o.text_field :access_code, class: "form-control" %>
</div>
</fieldset>
<% end %>
<div class="form-actions">
<%= f.submit "Create Account", class: "btn btn-primary" %>
<%= link_to "Cancel", :back, class: "text-btn" %>
</div>
<% end %>
edit.html.erb
<% provide(:title, "Edit User: #{#user.full_name} (#{#user.organization.name})") %>
<h1>Edit User: <%= #user.full_name %> (<%= #user.organization.name %>)</h1>
<p>Use the form below to manage your account.</p>
<%= nested_form_for([:admin, #user], html: {role: "form"}) do |f| %>
<%= render "shared/error_messages", obj: #user %>
<fieldset>
<legend>User Information</legend>
<div class="form-group">
<%= f.label :full_name, "Full Name" %>
<span class="help-block">How should others see you?</span>
<%= f.text_field :full_name, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :email %>
<span class="help-block">Your email address is used as your login.</span>
<%= f.text_field :email, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, placeholder: "leave blank to keep password unchanged", class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :password_confirmation, "Confirm Password" %>
<%= f.password_field :password_confirmation, class: "form-control" %>
</div>
</fieldset>
<% if #user.is_admin? %>
<%= f.fields_for :organization do |o| %>
<fieldset>
<legend>Associated Organization</legend>
<div class="form-group">
<%= o.label :name, "Organization Name" %>
<span class="help-block">This is the name of the organization you are a part of.</span>
<%= o.text_field :name, class: "form-control", value: #user.organization.name %>
</div>
<div class="form-group">
<%= o.label :access_code, "Organization Access Code" %>
<span class="help-block">Leaving this field blank will setup a new organization.</span>
<%= o.text_field :access_code, class: "form-control", value: #user.organization.access_code %>
</div>
</fieldset>
<% end %>
<%= f.hidden_field :organization_id %>
<% end %>
<div class="form-actions">
<%= f.submit "Update User", class: "btn btn-primary" %>
<%= link_to "Cancel", :back, class: "text-btn" %>
</div>
<% end %>
Ok, those are all the files making it happen. Now, i have the application doing almost everything i need it to do but this doesn't feel like production-level code to me.
One issue i know i am having is that if a user types something in the organization field and nothing else the controller will create and save the organization and then render the form back with the user validation errors. I don't want it to save the organization if there are validation errors in the user model.
I'm really just asking for advice if there is a better way of doing what i am trying to do. If you can't tell exactly what i'm trying to do with this code or have any questions please let me know!
Take a look at this post: http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/
Of particular interest will be the section on "3. Extract Form Objects".

Resources