a new page, nested form using devise's registration path - ruby-on-rails-3

I'm trying to build a nested form in a custom page using devise.
The error that comes out is: undefined method `build_profile' for nil:NilClass
<%= form_for("user", :url => user_registration_path) do |f| %>
<%= f.email_field :email, :autofocus => true, :placeholder => 'E-mail Address' %>
<%= f.password_field :password, :placeholder => 'Password' %>
<%= f.password_field :password_confirmation, :placeholder => 'Password Confirmation' %>
<% #user.build_profile %>
<%= f.fields_for :profile do |profile_form| %>
<%= profile_form.text_field :name, :placeholder => 'Name' %>
<%= profile_form.text_field :address, :placeholder => 'Address' %>
<%= profile_form.phone_field :phone, :placeholder => 'Phone (example: 0193284647)' %>
<% end %>
<p><%= f.submit "Sign up", :class=>'btn btn-primary' %> </p>
<% end %>
Edit (Extra information):
should i add #user = #user.build_profile by creating a users_controller.rb instead?
Would it cause problems with devise?

yes you have to do
#user = #user.build_profile
in registrations_controller.rb . And,mention the customize controller in routes.rb in devise method.
You should so something like
class Registrations < Devise::RegistrationsController
def new
#user = User.new
#user = #user.build_profile
super
end
end

Related

How to disable certain check_boxes when using Formtastic's :as => :check_boxes

<%= semantic_form_for [:admin, #admin] do |f| %>
<%= f.inputs do %>
<%= f.input :name %>
<%= f.input :email, :as => :email %>
<%= f.input :password, :as => :password %>
<%= f.input :password_confirmation, :as => :password %>
<%= f.input :admin_roles, :as => :check_boxes, :required => true, :disabled => [1] %>
<% end %>
<%= f.actions %>
<% end %>
-
<%= f.input :admin_roles, :as => :check_boxes, :required => true, :disabled => [1] %>
Passing an array to the above code disables the checkbox with id=1, which is nice. But I want to check the model of each checkbox, too see if it has a specific value, so I can disable it or not.
do_not_disable_checkbox if admin_role.do_not_show_me_boolean_field
Do I need to iterate each of my :admin_roles and output a checkbox for each? Or can I do it in one line like above? I'm new to rails and ruby, and I can't wrap my head around it and hoping for some help to put me in the right direction.

Rails 3 Mass-Assignment Errors with fields_for

I have the following model relationships:
OrderModel:
has_one :credit_card
accepts_nested_attributes_for :credit_card
attr_accessible :user_id, :date_updated, :date_finished, :amount, :payment_method, :status, :billing_cycle, :auth_net_subscription_id, :billing_start_date, :credit_card_attributes, :billing_address_id, :cc_id
CreditCardModel:
belongs_to :order
Here is my Order Controller (orders#checkout)
def checkout
#order = current_order
#cc = CreditCard.new
#order.build_credit_card
respond_with #order
end
Here is the form for entering in a CC on the order:
<%= form_for(#order, :url => finish_checkout_path, :html => { :class => 'validate' }) do |f| %>
<%= f.fields_for #cc do |cc| %>
<%= cc.text_field :cc_number, :placeholder => "Credit Card Number", :class => "full-width validate[required, creditCard] cc" %>
<%= cc.text_field :name, :placeholder => "Name as it appears on card", :class => "full-width validate[required]" %>
<%= select_month(Date.today, {:field_name => 'exp_month', :prefix => "order[credit_card]", :prompt => "EXP. MONTH"}, { :class => "dk half-width validate[required,past] marginRight10" }) %>
<%= select_year(Date.today, {:field_name => 'exp_year', :prefix => "order[credit_card]", :prompt => "EXP. YEAR", :start_year => Date.today.year, :end_year => Date.today.year + 10}, { :class => "dk half-width validate[required]" }) %>
<%= link_to "What's this?", "#", :class => 'cvv-help' %>
<%= cc.text_field :cvv, :class => 'half-width validate[required] marginRight10', :placeholder => "CVV" %>
<%= cc.text_field :zip_code, :class => 'half-width validate[required]', :placeholder => "Zip Code" %>
<% end %>
<%= f.hidden_field :amount, :value => #order.products.collect(&:price).reduce(&:+) %>
<p class="tos">By clicking the button below you agree to our terms of service.</p>
<p class="align-center"><%= f.submit "Submit", :class => 'btn submit' %></p>
<% end %>
And here is where I update the order (orders#finish):
current_order.update_attributes(params[:order])
When I do this, I get the following error: Can't mass-assign protected attributes: credit_card
I clearly have the credit_card_attributes in my attr_accessibleso I am not sure why this is erroring out.
Not sure, but it might be because of your controller code:
def checkout
#order = current_order
#cc = CreditCard.new
#order.build_credit_card
respond_with #order
end
With this, the credit card that you use in your fields_for is not linked to your order. That might be the problem.
Try doing that:
def checkout
#order = current_order
#order.build_credit_card
respond_with #order
end
and
<%= f.fields_for :credit_card do |cc| %>

Rails is not creating hidden field for put method on an update form

I have a REST resource called Greetings.
Here is my routes file:
resources :greetings
I have a form to create or update a greeting as follows:
<%= form_tag(#greeting, :remote => true, :id => 'greeting_form') do %>
<%= text_area :greeting, :content, :rows => 3, :placeholder => "Type your message..." %>
<% end %>
note: I am using form_tag because this form also collects user data.
This is supposed to create a hidden field with method=> put but its not so it can't find the route.
Any ideas how I can get this to submit to the update action?
Just write
<%= form_tag(#greeting, :remote => true, :id => 'greeting_form', :method => :put) do %>
and everything should be working.
You can use form_for tag and still collect user data like this:
<%= form_for #greeting, :validate => true do |f| %>
<%= f.text_area :content, :rows => 3, :placeholder => "Type your message..." %>
<%= f.fields_for #user do |u| %>
<%= u.text_field :name %>
<% end %>
<% end

undefined method `users' for nil:NilClass

I am trying to create an application having domains and users, there are 3 types of users, super admin,domain admins and domain users.All the users(3 types) are in the users table and domains in domain table. At present there are domains and super admin. A super admin can login and create domains and domain users. The domains users should be related to a particular domain(i have a "domain_id" column in my 'users' table).Now when i am trying to create a user under a domain(after selecting a domain), i am getting this error "undefined method `users' for nil:NilClass".
My user controller.
def new
#domain = Domain.find(params[:id])
#user = User.new
#title = "Sign up"
end
def create
#user = #domain.users.build(params[:user])
if #user.save
flash[:success] = "Welcome to My Space!"
redirect_to #user
else
#title = "Sign up"
render 'new'
end
end
My user model is having.
belongs_to :domain
validates :domain_id, :presence => true
and domain model is having.
has_many :users
My new.html.erb form
<%= form_for #user do |f| %>
<%= f.label :first_name %>
<%= f.text_field(:first_name, :size => 20) %>
<%= f.label :last_name %>
<%= f.text_field(:last_name, :size => 20) %>
<%= f.label :email %>
<%= f.text_field(:email, :size => 20) %>
<%= f.label :password %>
<%= f.password_field(:password, :size => 20) %>
<%= f.label :password_confirmation, "Verify Password" %>
<%= f.password_field(:password_confirmation, :size => 20) %>
<%= f.submit "Create" %>
<% end %>
Assuming #domain = Domain.find(params[:id]) in the new method does what it should do:
def new
#domain = Domain.find(params[:id])
#user = #domain.users.build
#title = "Sign up"
end
def create
#user = User.new(params[:user])
if #user.save
flash[:success] = "Welcome to My Space!"
redirect_to #user
else
#title = "Sign up"
render 'new'
end
end
And your view should look like this:
<%= form_for #user do |f| %>
<%= f.hidden_field :domain_id %>
<%= f.label :first_name %>
<%= f.text_field(:first_name, :size => 20) %>
<%= f.label :last_name %>
<%= f.text_field(:last_name, :size => 20) %>
<%= f.label :email %>
<%= f.text_field(:email, :size => 20) %>
<%= f.label :password %>
<%= f.password_field(:password, :size => 20) %>
<%= f.label :password_confirmation, "Verify Password" %>
<%= f.password_field(:password_confirmation, :size => 20) %>
<%= f.submit "Create" %>
<% end %>
Because of the hidden domain_id field in your form, the user will be assigned to the correct domain.

Rails 3: how to pull change password out to be its own separate form from devise

I'm using devise for my user registrations and I'd like to have a separate edit path for user's to change/update their passwords. I've pulled the devise registrations views out and created a separate registrations controller like described in Railscast 236
I've tried creating a new action called change_password in the registrations controller but when I try to set the route with match '/change_password', to => 'registrations#change_password' I get an AbstractController::Actions Not Found
registrations controller
class RegistrationsController < Devise::RegistrationsController
def create
super
session[:omniauth] = nil unless #user.new_record?
end
def destroy
resource.destroy
set_flash_message :notice, :destroyed
sign_out_and_redirect(self.resource)
end
def change_password
render_with_scope :edit
end
private
def build_resource(*args)
super
if session[:omniauth]
#user.apply_omniauth(session[:omniauth])
#user.valid?
end
end
routes.rb
match 'auth/:provider/callback' => 'authentications#create'
resources :authentications
devise_for :users, :controllers => {:registrations => 'registrations'}
resources :posts do
member do
get :likers
end
collection do
get :search
end
end
resources :relationships, :only => [:create, :destroy]
resources :appreciations, :only => [:create, :destroy]
root :to => "pages#home"
match '/contact', :to => 'pages#contact'
match '/about', :to => 'pages#about'
match '/help', :to => 'pages#help'
match '/blog', :to => 'pages#blog'
resources :users do
member do
get :following, :followers, :likes
end
resources :collections
end
end
views/registrations/change_password.html.erb
<h2>Edit <%= resource_name.to_s.humanize %></h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :validate => true,
:html => { :method => :put }, :html => {:multipart => true}) do |f| %>
<%= devise_error_messages! %>
<p><strong>To change password, otherwise leave blank.</strong></p>
<p><%= f.label :current_password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :current_password %></p>
<p><%= f.label :password, "New password" %> <br />
<%= f.password_field :password %></p>
<p><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></p>
</div><br />
<p><%= f.submit "Update" %></p>
<% end %>
Try to pass match .. in the block of devise_for helper:
devise_for :users, :controllers => {:registrations => 'registrations'} do
match '/change_password', to => 'registrations#change_password'
end
I found this to be the easiest way to split the user edit form into edit & account
Originally I had
:name,
:email,
:avatar,
:location,
:website,
:bio,
:password (all in one form)
ROUTES (this provides route:
account_user GET /users/:id/account(.:format) users#account)
resources :users do
member do
get :following, :followers, :account
end
end
USERS_CONTROLLER.RB
before_filter :signed_in_user, only: [:index, :edit, :update, :destroy, :following, :followers, :account]
before_filter :correct_user, only: [:edit, :update, :account]
def edit
#user = User.find(params[:id])
end
def account
#title = "Account"
#user = User.find(params[:id])
end
def update
if #user.update_attributes(params[:user])
flash[:success] = "Profile updated"
sign_in #user
redirect_to #user
elsif #title = "Account"
render 'account'
else
render 'edit'
end
end
(split form views)
EDIT.HTML.ERB
<%= form_for #user, :html => { :multipart => true } do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :avatar %><br />
<%= f.file_field :avatar %>
<%= f.label :location %>
<%= f.text_field :location %>
<%= f.label :website %>
<%= f.text_field :website %>
<%= f.label :bio %>
<%= f.text_area :bio, placeholder: "About yourself in 160 characters or less..." %>
<%= f.submit "Update Profile", class: "btn btn-medium btn-primary" %>
<% end %>
ACCOUNT.HTML.ERB
<%= form_for #user, :html => { :multipart => true } do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation, "Confirm Password" %>
<%= f.password_field :password_confirmation %>
<%= f.submit "Update Account", class: "btn btn-medium btn-primary" %>
<% end %>
SIDE NAV BAR INSIDE OF EDIT AND ACCOUNT VIEWS, SO THE USER HAS ACCESS TO EDIT AND ACCOUNT FORM
<ol class="nav nav-tabs nav-stacked">
<% #user ||= current_user %>
<li>
<a href="<%= edit_user_path(#user) %>">
Profile
<i class="icon-chevron-right"></i>
</a>
</li>
<li>
<a href="<%= account_user_path(#user) %>">
Account
<i class="icon-chevron-right"></i>
</a>
</li>
</ol>