ArgumentError for partial form, First argument in form cannot contain nil or be empty - forms

My registration form was working just fine, but once I moved the registration from into a partial _signup.html.erb it has give me the error "First argument in form cannot contain nil or be empty"
I want to have the user registration from go through a modal from from the homepage instead of being redirected to new.html.erb.
static_pages/home.html.erb
<% else %>
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
Sign up with email
</button>
<div class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Sign up</h4>
</div>
<div class="modal-body">
<%= render partial: 'users/signup', locals: {user: #user} %>
</div>
</div>
</div>
</div>
<% end %>
and in the partial _signup.html.erb
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#user) do |f| %>
<form id="SignupForm">
<%= render 'shared/error_messages' %>
<fieldset>
<legend>Fill in your info</legend>
<%= f.label :username %>
<%= f.text_field :username, class: 'form-control' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<fieldset>
</fieldset>
<legend>Languages</legend>
<label for="Gender">Select gender</label>
<%= f.select :sex, options_for_select([['Select Gender', ''],['Male','1'],['Female','2']], "#{#user.sex}") %>
<label for="Country">Fill in your location</label>
<%= f.country_select :country_code, { priority_countries: ["GB", "US"] }, class: 'required-field', required: true %>
<%= f.submit "Create my account", class: "btn btn-primary" %>
<% end %>
</fieldset>
</form>
</div>
</div>
part of the users_controller.rb
class UsersController < ApplicationController
respond_to :html, :js
before_action :logged_in_user, only: [:index, :show, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
def index
#users = User.paginate(page: params[:page])
end
def show
#user = User.find(params[:id])
#page_name = "user_page"
end
def new
#user = User.new
end
def signup
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
#user.send_activation_email
flash[:info] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
routes.rb
Rails.application.routes.draw do
root to: 'static_pages#home'
get 'help' => 'static_pages#help'
get 'about' => 'static_pages#about'
get 'contact' => 'static_pages#contact'
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
get "users/signup" => 'users#signup'
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
end

You don't have access to the instance variable #user in a partial. You have to pass it as a local variable:
static_pages/home.html.erb
<div class="modal-body">
<%= render partial: 'users/signup', locals: {user: #user} %>
</div>
And in your form partial you have to use that user local variable:
_signup.html.erb
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(user) do |f| %>
<form id="SignupForm">
<%= render 'shared/error_messages' %>
<fieldset>
<legend>Fill in your info</legend>
<%= f.label :username %>
<%= f.text_field :username, class: 'form-control' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<fieldset>
</fieldset>
<legend>Languages</legend>
<label for="Gender">Select gender</label>
<%= f.select :sex, options_for_select([['Select Gender', ''],['Male','1'],['Female','2']], "#{user.sex}") %>
<label for="Country">Fill in your location</label>
<%= f.country_select :country_code, { priority_countries: ["GB", "US"] }, class: 'required-field', required: true %>
<%= f.submit "Create my account", class: "btn btn-primary" %>
<% end %>
</fieldset>
</form>
</div>
</div>

Related

Ruby on Rails. How to combine a search form with bootstrap style?

How to combine this search form
<%= form_tag index_path, :method => 'get' do %>
<%= text_field_tag :search, params[:search]%>
<%= submit_tag "search", :title => nil %>
<% end %>
with this bootstrap style
<div class="row">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for...">
<span class="input-group-btn">
<button class="btn btn-default" type="button">search</button>
</span>
</div>
</div>
You can add any class you like to any Rails form tag. You just need to be careful that your method call matches one of the valid call signatures for the tag helper. For instance, the API for the form tag is documented here.
Here is my take on combining the above. This may need some tuning:
<div class="row">
<%= form_tag index_path, :method => 'get', class: 'input-group' do %>
<%= text_field_tag :search, params[:search], class: 'form-control', placeholder: 'Search for...' %>
<span class="input-group-btn">
<%= submit_tag "search", class: "btn btn-default" %>
</span>
<% end %>
</div>

Nested attributes for belongs_to association rails

I have two models, Complaint and Company. Complaint belongs_to and accepts_nested_attributes for Company, and Company has_many Complaints.
# Models
class Complaint < ActiveRecord::Base
attr_accessible :complaint, :date, :resolved
belongs_to :user, :class_name => 'User', :foreign_key => 'id'
belongs_to :company, :class_name => 'Company', :foreign_key => 'id'
has_many :replies
accepts_nested_attributes_for :company
end
class Company < ActiveRecord::Base
attr_accessible :name
has_many :complaints, :class_name => 'Complaint', :foreign_key => 'id'
has_many :branches, :class_name => 'Branch', :foreign_key => 'id'
belongs_to :industry
end
In the Complaint Controller I try build a Company in the new method.
# Complaint Controller
class ComplaintsController < ApplicationController
...
def new
#complaint = Complaint.new
#complaint.build_company
respond_to do |format|
format.html # new.html.erb
format.json { render json: #complaint }
end
end
...
end
In the form I have added a field for adding a name attribute to the Company.
# Complaint Form
<%= form_for(#complaint) do |f| %>
<% if #complaint.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#complaint.errors.count, "error") %> prohibited this complaint from being saved:</h2>
<ul>
<% #complaint.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :complaint %><br />
<%= f.text_area :complaint, :rows => 5 %>
</div>
<div class="field">
<%= f.label :date %><br />
<%= f.datetime_select :date %>
</div>
<% if current_user.try(:admin?) %>
<div class="field">
<%= f.label :resolved %><br />
<%= f.check_box :resolved %>
</div>
<% end %>
<%= fields_for :company do |company| %>
<div class="field">
<%= company.label :name, 'Company' %>
<%= company.text_field :name %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
The form submits but only the Complaint is saved. The user input for Company is disregarded. Why won't this create a new Company?
My mistake was in the form. I missed the f. before the fields_for :company
<%= f.fields_for :company do |company| %>

Access subcollection in mongoid with rails form to edit and create new entry

I am using mongodb with mongoid in rails3. I am newbie to all this. My models are as shown below.
class Californium
include Mongoid::Document
field :first_name
field :License_type
Field :Licese_expiry_date
embeds_one :address
end
class Address
include Mongoid::Document
field :street
field :city
field :state
field :zip
embedded_in :Californium, :inverse_of => :address
end
My Controller
class CaliforniaController < ApplicationController
def index
#california = Californium.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #california }
end
end
def show
#californium = Californium.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #californium }
end
end
# Here is where I have problem. I am not able to show a
# form with californium address details. My form view is show after the controller
def new
#californium = Californium.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #californium }
end
end
def edit
#californium = Californium.find(params[:id])
end
end
My form
<%= form_for(#californium) do |f| %>
<div class="field">
<%= f.label :license_number %><br />
<%= f.text_field :license_number %>
</div>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :license_type %><br />
<%= f.text_field :license_type %>
</div>
<div class="field">
<%= f.label :license_status %><br />
<%= f.text_field :license_status %>
</div>
<div class="field">
<%= f.label :license_expire_date %><br />
<%= f.text_field :license_expire_date %>
</div>
<div class="field">
<%= f.label :license_issue_date %><br />
<%= f.text_field :license_issue_date %>
</div>
<div class="field">
# Here I am not able to access :address.street and :address.city as it is an other
# model embedded in californium
<%= f.label :address.street %><br />
<%= f.text_field :address.street %>
</div>
<div class="field">
<%= f.label :address.city %><br />
<%= f.text_field :address.city %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I am trying to build a form where in all the details of the californium could be edited. I am not able to access californium's address details as it is a subcollection of californium collection. I am able to display all the details of the californium including the address but dont how to create a editable form.
Try using the form helper "fields_for" for your embedded model as in the following working example.
Hope that this helps.
It took a while to wade through the typos and inconsistencies, so if you want a faster answer in the future,
please make your question both as accurate and as minimal as possible.
class Californium
include Mongoid::Document
field :name
field :license_type
embeds_one :address
end
class Address
include Mongoid::Document
field :street
field :city
field :state
field :zip
embedded_in :california, :inverse_of => :address
end
app/views/edit.html.erb
<%= form_for :californium do |f| %>
<div class="field">
<%= f.label :name %>
<br/>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :license_type %>
<br/>
<%= f.text_field :license_type %>
</div>
<%= fields_for #californium.address do |af| %>
<div class="field">
<%= af.label :street %>
<br/>
<%= af.text_field :street %>
</div>
<div class="field">
<%= af.label :city %>
<br/>
<%= af.text_field :city %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
config/routes.rb
match 'california/:id' => 'california#edit', via: :get
match 'california/:id' => 'california#update', via: :post
test/functional/california_controller_test.rb
require 'test_helper'
class CaliforniaControllerTest < ActionController::TestCase
def setup
Californium.delete_all
end
test "form" do
cal = Californium.create(name: 'Benjamin Spock', license_type: 'MD', address: Address.new(street: '311 Temple St', city: 'New Haven', state: 'CT', zip: '06511'))
assert_equal(1, Californium.count)
p Californium.find(cal.id)
get :edit, id: cal.id
assert(assigns(:californium))
assert_response(:success)
puts #response.body
end
end

Can't validate phone number

I'm trying to validate a phone number without success. When I submit the form for the following model, it always accepts the phone number I put in, whether it's valid or not. Why is this happening?
class Client < ActiveRecord::Base
belongs_to :salon
belongs_to :address
accepts_nested_attributes_for :address
attr_accessible :address_attributes, :name, :phone, :email
validates_presence_of :name
validates_presence_of :email
validates_presence_of :phone,
:unless => Proc.new { |c| c.phone.gsub(/[^0-9]/, "").length != 10 }
end
-
<%= form_for(#client) do |f| %>
<% if #client.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#client.errors.count, "error") %> prohibited this client from being saved:</h2>
<ul>
<% #client.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.hidden_field :salon_id, :value => Salon.logged_in_salon.id %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :phone %><br />
<%= f.text_field :phone %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<%= f.fields_for :address do |address_form| %>
<div class="field">
<%= address_form.label :line1 %><br />
<%= address_form.text_field :line1 %>
</div>
<div class="field">
<%= address_form.label :line2 %><br />
<%= address_form.text_field :line2 %>
</div>
<div class="field">
<%= address_form.label :city %><br />
<%= address_form.text_field :city %>
</div>
<div class="field">
<%= address_form.label :state_id %><br />
<%= select("client[address]", "state_id", State.all.collect {|s| [ s.name, s.id ] }) %>
</div>
<div class="field">
<%= address_form.label :zip %><br />
<%= address_form.text_field :zip %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
You should be using validates_format_of instead of validates_presence_of. Something like:
validates_format_of :phone,
:with => /\A[0-9]{10}\Z/,
:allow_blank => true,
:allow_nil => true

How to set a file_upload control for a field in rails_admin?

I'm new to rails and I recently discovered rails_admin.
How to set a file_upload control for a field in rails_admin?
If you are using the Carrierwave gem for your file uploads you can do something like this
https://gist.github.com/884835 or in erb if you prefer that:
<%= label_tag "#{field.abstract_model.to_param}_#{field.name}", field.label %>
<div class="input">
<% image = field.bindings[:object].send(field.name) %>
<% if image.path %>
<div class="row">
<% default_version = image.versions[:main] %>
<%= image_tag default_version && default_version.url || image.url %>
<br />
<%= form.check_box "remove_#{field.name}" %>
<%= form.label "remove_#{field.name}", "Remove existing #{field.label.downcase}", :class => "inline" %>
</div>
<% end %>
<div class="row">
<%= form.file_field field.name, :class => "fileUploadField #{field.has_errors? ? "errorField" : nil}" %>
<%= form.hidden_field "#{field.name}_cache" %>
</div>
</div>