How to initiate new profile object (has_one) after successful registration with Rails3 & devise - ruby-on-rails-3

So I have devise setup to perform registration. After registration the user is redirected to profiles#new however I can't attach profile to current_user id
Actually it doesn't work at all. Here is what I have in my profiles_controller.rb
# POST /profiles
def create
#profile = current_user.Profile.new(params[:profile])
respond_to do |format|
if #profile.save
format.html { redirect_to(#profile, :notice => 'Profile was successfully created.') }
else
format.html { render :action => "new" }
end
end
end
leading to undefined method `Profile' for #

So the User model has_one :profile ?
If so, you likely want:
#profile = current_user.profile.build(params[:profile])
Note that case ('profile' vs 'Profile') is important here.

I think that you should use
#profile = current_user.build_profile(params[:profile])
Check rails api here

Related

Unpermitted parameters although controller has them whitelisted when creating user

In migrating a rails application from 3.2 to 4.1, I am hitting some issues with user creation. As there is a need to distinguish the current_user form a local_user. The controller create action
def create
#local_user = User.new(user_params)
respond_to do |format|
if #local_user.save
if params[:user][:avatar].present?
format.html { render :crop }
else
format.html { redirect_to(admin_user_path(#local_user), :notice => 'User was successfully created.') }
end
else
format.html { render :action => "new" }
end
Generates a console error: Unpermitted parameters: name, surname, pen_name[...], yet the User controller defines them:
def user_params
params.require(:user).permit(:name, :surname, :pen_name, [...])
end
The form call is:
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :method => :post, :validate => true) do |f| %>
This is necessarily a devise issue for a user can be created with the scaffolding for the User class with the exact same variables. There is some logic that devise is going through which does not pull all the controller logic ; what am I missing?
Needs a devise specific initializer, as per this demo, where all variables can be entered as an array.

Devise: after_sign_in_path_for(resource) not working

I am using devise for user sign up/in. But when user signs in from public accessible pages, devise redirects to root_path.
I tried to use this:
def after_sign_in_path_for(resource)
request.referrer
end
When user tries to sign in, it gives error 'not redirected properly'.
Can anybody tell how to do it?
I believe if I am right what you want to do is override the redirect when a user sign in is to change the following method inside controllers/devise/sessions_controller.rb If you haven't generated devises controllers you generate devise controller. Having done that you will want to have something like the following inside your devise/sessions_controller.rb
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
# respond_with resource, :location => after_sign_in_path_for(resource)
if current_user.role? :administrator
redirect_to dashboard_path
else
redirect_to rota_days_path
end
end
In the above example by default the sessions_controller - create method uses the following: # respond_with resource, :location => after_sign_in_path_for(resource) which I have commented out. By adding a if statement that checks if the current_users role is an administrator. If they then they are redirected to the dashboard page. If not then they are redirected to the rota page.
Alternatively the devise helpers state that you could also do something like:
def after_sign_in_path_for(resource)
stored_location_for(resource) ||
if resource.is_a?(User) && resource.can_publish?
publisher_url
else
super
end
end
Hope this helps.
Update
def create
#hospital_booking = HospitalBooking.new(params[:hospital_booking])
respond_to do |format|
if #hospital_booking.save
format.html { redirect_to :back, notice: 'Photographer Shift was successfully created.' }
format.json { render json: #hospital_booking, status: :created, location: #hospital_booking }
else
format.html { render action: 'new' }
format.json { render json: #hospital_booking.errors, status: :unprocessable_entity }
end
end
end
What happens here is when the hospital_booking is saved it redirects back to the issue page instead of redirecting to another page. Further reading here: api dock- redirect_to

rspec controller test with devise authentication

I am having problem with rspec testing controller the devise authentication.
I have a following setup
I have included
config.include Devise::TestHelpers, :type => :controller
in my spec_helper.rb
In my merchants_controller_spec.rb
describe MerchantsController do
before :each do
#user = Factory(:user)
#merchant = Factory(:merchant, :user_id => #user.id,:is_approved => false, :is_blacklisted => false)
controller.stub!(:current_user).and_return(#user)
end
describe "GET index" do
it "assigns all merchants as #merchants" do
merchant = Factory(:merchant,:is_approved => true, :is_blacklisted => false)
get :index
assigns(:merchants).should eq([merchant])
end
end
end
My merchants_controller.rb
class MerchantsController < ApplicationController
before_filter :authenticate_user!
def index
#merchants = Merchant.approved
debugger
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #merchants }
end
end
end
I have a scope approved in merchant model
scope :approved, where(:is_approved => true, :is_blacklisted => false)
Now my problem is even though i stubbed current_user and returned #user as current_user, My merchants_controller index spec is failing. But if i comment out authenticate_user! then the spec passes,
without authenticate_user! the debugger of index action is caught but with authenticate_user! debugger is not caught.
I think there is problem in subbing current_user and i am not able to figure it out.
Help me out..
Have you read through the docs on github?:
Devise includes some tests helpers for functional specs. To use them, you just need to include Devise::TestHelpers in your test class and use the sign_in and sign_out methods. Such methods have the same signature as in controllers:
sign_in :user, #user # sign_in(scope, resource)
sign_in #user # sign_in(resource)
sign_out :user # sign_out(scope)
sign_out #user # sign_out(resource)
Another alternative
RSpec.describe YourController, :type => :controller do
before do
user = FactoryGirl.create(:user)
allow(controller).to receive(:authenticate_user!).and_return(true)
allow(controller).to receive(:current_user).and_return(user)
end
# rest of the code
end

Troubleshooting two-step nested model signup process

I want to initiate a sign-up process on my homepage. In the end, the process ideally would follow the following logic:
user = User.new
user.email = ""
user.password = ""
user.profile = Profile.new
user.profile.info = ""
user.profile.save
user.save
I'll be using nested model forms, of course. But is there a way to spread this into two parts? In part 1 the User would enter mainly user information, as well as a bit of profile information, and part 2 would contain solely 'profile' information. Then when all is said and done the user gets redirected to their user profile.
If this is possible, what is the general thinking on this type of process? Second, I'm wondering if someone can help me figure out how to achieve it. I have the nested model forms all set up but there must be something messed up in my routes.rb file/Controllers that is denying me the experience.
Here's my routes.rb file.
get "profiles/show"
get "/profiles/:id" => "profiles#show", :as => "profile"
post "/signup" => "profiles#create", :as => "signup"
get "skip/signup", :to => "users#newskip"
match "skip/profiles/new", :to => "profiles#newskip"
root :to => "users#new"
And here are my UsersController and ProfilesController respectively:
*class UsersController < ApplicationController*
before_filter :authenticate, :only => [:edit, :update]
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to signup_path, :notice => 'User successfully added.'
else
render :action => 'new'
end
end
*class ProfilesController < ApplicationController*
before_filter :authenticate, :only => [:edit, :update]
def new
#user.profile = Profile.new
end
def create
#profile = Profile.new(params[:profile])
if #profile.save
redirect_to profile_path(#profile), :notice => 'User successfully added.'
else
render :action => 'new'
end
end
Can anyone help show me the light? I know Devise is a solution but I'm trying to learn without that. At least at first. This previous question/answer looks like a potential starter.
Here is a Railscast about multistep forms. I think it should put you on track for what you're trying to accomplish.
I completed this by having user and profile create on the homepage, Profiles#edit as the second step, with a redirect_to profile.

Rails 3 - Nested Resources Routing - One to One relationship

Having some trouble with some nested resources routing. What I'm trying to do is link to a user's profile page for editing purposes. In my view it is written as:
<%= link_to "Edit Profile", edit_user_profile_path(current_user) %>
Which errors out with:
No route matches {:action=>"edit", :controller=>"profiles", :user_id=>#<User id: 1, email: "EDITEDOUT", hashed_password: "EDITEDOUT", created_at: "2011-01-20 18:30:44", updated_at: "2011-01-20 18:30:44">}
In my routes.rb file, it looks like so:
resources :users do
resources :profiles, :controller => "profiles"
end
I checked my Rake routes, and it gave me this as a valid option:
edit_user_profile GET /users/:user_id/profiles/:id/edit(.:format) {:action=>"edit", :controller=>"profiles"}
Which I am able to manually navigate to. For good measures, here's proof of my controller:
class ProfilesController < ApplicationController
def edit
#user = current_user
#profile = current_user.profile
end
def update
#user = current_user
#profile = current_user.profile
respond_to do |format|
if #profile.update_attributes(params[:profile])
format.html { redirect_to(orders_path, :notice => "Your profile has been updated.") }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #profile.errors, :status => :unprocessable_entity }
end
end
end
end
Anyway, I've been having some problem tracking this down. Any pointers would help. For my DB design Profiles belong to Users in a one-to-one relationship. I'm hoping it's just something newbish I'm not noticing a new set of eyes might help.
If you look closely at your route, you'll see that it expects both a :user_id and an :id. The latter, in this case, refers to the user profile.
In order to tell Rails that you want that particular profile, you'll have to specify both the user and the profile in your link, like this:
edit_user_profile_path(current_user, #profile)
Now, Rails will use the first argument (current_user) for the :user_id part of the route, and the second argument (#profile) for the :id.