Reputation: 2051
I have a user model that has fields for first_name, last_name, email, and password. After a user signs up under their user profile page I would like to allow certain fields and not others to show on a form to update part of the user info.
For example I would like just the first_name to be shown as a field when I render a form for them to edit their name. How do I handle this? Should I make a new route and a controller action that lets me update just this one field? or do I just hide all the other fields and submit them in the background without the user seeing them?
<div class="signup_user">
<div class="container-fluid">
<div class="col-md-5 col-sm-12 centered">
<%= form_for(@user) do |form| %>
<%= render "shared/errors", object: @user %>
<%= render "shared/flash" %>
<div class="card card-default">
<div class="card-body">
<h1>Create account</h1>
<%= form.label :first_name %>
<%= form.text_field :first_name, size: 40, autofocus: true, class: "required form-control" %>
<%= form.label :last_name %>
<%= form.text_field :last_name, size: 40, class: "required form-control" %>
<%= form.label :email %>
<%= form.email_field :email, size: 40, class: "required form-control" %>
<%= form.label :password %>
<%= form.password_field :password, size: 40, placeholder: "At least 10 characters", class: "required form-control" %>
<%= form.label :password_confirmation, "Confirm Password" %>
<%= form.password_field :password_confirmation, size: 40, class: "required form-control" %><br>
<%= form.submit "Submit", class: 'btn btn-block btn-outline-primary' %>
<% end %>
<hr>
<p>Already have an account? <%= link_to "Sign In", new_session_path %></p>
</div>
</div>
</div>
</div><!--./container-->
</div><!--./signup_user-->
after the initial signup I would like to just show 1 field like this for editing just the user name.
<div class="signup_user">
<div class="container-fluid">
<div class="col-md-5 col-sm-12 centered">
<%= form_for(@user) do |form| %>
<%= render "shared/errors", object: @user %>
<%= render "shared/flash" %>
<div class="card card-default">
<div class="card-body">
<%= form.label :first_name %>
<%= form.text_field :first_name, size: 40, autofocus: true, class: "required form-control" %>
</div>
</div><!--./container-->
</div><!--./signup_user-->
Upvotes: 1
Views: 1568
Reputation: 6981
I'd make two definitions of strong parameters on the controller:
def create_params
params.require(:user).permit(:first_name, :last_name, :email, :password)
end
def update_params
params.require(:user).permit(:email, :password)
end
Then in your create
/update
methods just allow each different definition. You don't need a new view or a new model if you just restrict the params based on the action.
def create
@user.create(create_params)
redirect_to users_path
end
def update
@user.update_attributes(update_params)
redirect_to users_path
end
Makes sense to me, and that way you don't have to create anything superfluous. Then fields will be rejected in a secure way the way they should be. Then you can adjust the view with action_name == 'edit'
or similar.
Upvotes: 1
Reputation: 3935
The easiest way is use the action_name helper and create some conditional logic that will conditionally render the fields that you only want to show on the new action, e.g. action_name == "new"
Upvotes: 1
Reputation: 141
You can generate an additional view by creating a new model.
Example :
models/user_edit.rb
class User_Edit < User
end
models/user.rb
class User < ApplicationRecord
...
end
routes
resources :users
devise_for :users, path: 'users', controllers: {
sessions: "users/sessions",
passwords: "users/passwords",
registrations: "users/registrations",
confirmations: "users/confirmations",
}
devise_for :users_edit, path: 'users_edit', controllers: {
registrations: "users_edit/registrations",
}
And so you will have :
views/users/registrations/edit.html
and
views/users_edit/registrations/edit.html
Upvotes: -1