I'm using devise for my user auth and registration. I can register a user no problem. Im also using friendly. My issue is, I can only create one user profile.
The setup...
user.rb:
class User < ActiveRecord::Base
extend FriendlyId
friendly_id :name, use: :slugged
validates :name, uniqueness: true, presence: true
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_one :profile # each user should have just one profile
end
profile.rb:
class Profile < ActiveRecord::Base
belongs_to :user
end
profiles_controller.rb:
class ProfilesController < ApplicationController
before_action :authenticate_user!
before_action :only_current_user
def new
# form where a user can fill out their OWN profile
@user = User.friendly.find( params[:user_id] )
@profile = Profile.new
end
def create
@user = User.friendly.find( params[:user_id] )
@profile = @user.build_profile(profile_params)
if @profile.save # Not saving!!
flash[:success] = 'Profile Created!'
redirect_to user_path( params[:user_id] )
else
render action: :new # keeps rendering!
end
end
private
def profile_params
params.require(:profile).permit(:first_name, :last_name, :avatar, :job_title, :phone_number, :business_name)
end
end
Why is it that only one user can create a profile and not others? Is it has to do with the relations?
We use this setup with some of our apps - User
-> Profile
.
In short, you should build the profile at User creation. Then you can edit the profile as you need. Your problem of having a Profile.new
method is very inefficient...
#app/models/user.rb
class User < ActiveRecord::Base
has_one :profile
before_create :build_profile #-> saves blank associated "Profile" object after user create
end
This will mean that each time a User
is created, their corresponding Profile
object is also appended to the db.
This will give you the capacity to edit the profile as required:
#config/routes.rb
resources :users, path_names: { edit: "profile", update: "profile" }, only: [:show, :edit, :update]
This will give you the opportunity to use the following:
#app/controllers/users_controller.rb
class UsersController < ApplicationController
before_action :authenticate_user!, only: [:edit, :update]
before_action :authorize, only: [:edit, :update]
def show
@user = User.find params[:id]
end
def edit
@user = current_user
end
def update
@user = current_user
@user.update user_params
end
private
def authorize
id = params[:id]
redirect_to user_show_path(id) if current_user.id != id #-> authorization
end
def user_params
params.require(:user).permit(:x, :y, :z, profile_attributes: [:homepage, :other, :profile, :attributes])
end
end
The view/form would be the following:
#app/views/users/edit.html.erb
<%= form_for @user do |f| %>
<%= f.fields_for :profile do |f| %>
<%= f.text_field :homepage %>
...
<% end %>
<%= f.submit %>
<% end %>
In regards your current setup:
def new
@profile = current_user.profile.new
end
def create
@profile = current_user.profile.new profile_params
if @profile.save
redirect_to user_path(params[:id]), notice: "Profile Created!"
else
render action: :new
end
end
private
def profile_params
params.require(:profile).permit(:x, :y, :z)
end