I have a two models, Group and User
User belongs_to Group and
Group has_many Users
In my groups/show.html.erb I have the user sign-up form
<h1>Create user</h1>
<%= form_for #user do |f| %>
<%= render 'shared/error_messages', :object => f.object %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation, "Confirmation" %><br />
<%= f.password_field :password_confirmation %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
To get a relation between the Group and the User I have a create method in my Users controller as follows
def create
#group = Group.find(params[:group][:id])
#user = #group.users.build(params[:user])
if #user.save
flash[:success] = "You have created a new user"
redirect_to group_path
else
#title = "Create user"
render 'new'
end
end
I have also tried:
#group = Group.find(params[:id])
and
#group = Group.find(params[:group_id])
But I still get an error
Essentially I want to create new users in the group/show.html.erb and associate that user with the group where the user was created. If the user is created in groups/3 for example, how do I set my create method in the Users controller to make sure this relation holds?
In general I've been following the Hartl Rails tutorial book at http://ruby.railstutorial.org/chapters/user-microposts#sec:creating_microposts and following the approach for forms and create methods. However I am not sure how to get the params for groups/3 into the find method like #group = Group.find(?????)
Can someone please enlighten me, this issue has been bothering me for a few days now.
Thanks in advance
After the form is submitted, it takes you to the users#create. This route doesn't have a group_id segment.
To pass group_id there, you need to store it in a hidden field in your form.
Related
Rails 5.0.1
Devise 4.2.0
Hello, I'm building an app in which the user must fill a form to sign up, which includes the registration info for devise, and some personal info por their profile. I have made the models for user and profile, established their one to one relation, and added accept_nested_attributes_for :profile inside the user. I have also modified the registrations views to include f.fields_for for the profile, and until that point everything seems to work fine.
But, when I try to create a new user, and fill the required information, I get an error inside the view (from devise I guess) saying:
1 error prohibited this user from being saved
Profile user must exist
I have already followed many guides on how to create a nested form with devise, and none of them seem to have this issue, and I have also searched a lot with no answer. Here are some snippets from my registration controller, user and profile model, and registrations/new view:
registrations_controller
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: [:create]
before_action :configure_account_update_params, only: [:update]
def new
build_resources({})
resource.build_profile
respond_with self.resource
end
protected
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up,
keys: [:email, :password,
:password_confirmation,
profile_attributes: [:name, :art_name,
:birth_date, :location]])
end
User model
class User < ApplicationRecord
has_one :profile, dependent: :destroy
before_create :build_profile
accepts_nested_attributes_for :profile
# Devise configuration.....
end
Profile model
class Profile < ApplicationRecord
belongs_to :user
end
Registrations/new view
<h2>Nueva Cuenta</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<%= f.fields_for :profile do |b| %>
<div class="field">
<%= b.label :name, "Nombre" %><br />
<%= b.text_field :name %>
</div>
<div class="field">
<%= b.label :art_name, "Nombre artistico" %><br />
<%= b.text_field :art_name %>
</div>
<div class="field">
<%= b.label :birth_date, "Fecha de nacimiento" %><br />
<%= b.date_field :birth_date %>
</div>
<div class="field">
<%= b.label :location, "Ubicacion" %><br />
<%= b.text_field :location %>
</div>
<% end %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %>
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
My guess is that it has something to do with the sanitizers, I'm not completely sure how do I pass each attribute through, since most of the guides that explained this did with an older version of devise.
Thanks for your attention.
in your profile model, try this:
belongs_to :user, optional: true
it works for me
I have two models user and profile.
I want to save the username and password in user and other user profile details in
profile.
Now,
The user model has:
has_one :profile
accepts_nested_attributes_for :profile
attr_accessible :email, :password,:profile_attributes
The profile model has
belongs_to :user
attr_accessible :firstname, :lastname
The user controller has
def new
#user = User.new
#profileattr = #user.build_profile
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to root_url, :notice => "user created successfully!"
else
render "new"
end
end
The view new.html.erb have fields for both user and profile.
view has:
<%= form_for #user do |f| %>
<% if #user.errors.any? %>
<div class="error_messages">
<h2>Form is invalid</h2>
<ul>
<% for message in #user.errors.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :email %><br />
<%= f.text_field :email %>
</p>
<p>
<%= f.label :password %><br />
<%= f.password_field :password %>
</p>
<%= f.fields_for #profileattr do |pf|%>
<p>
<%= pf.label :firstname %><br />
<%= pf.text_field :firstname %>
</p>
<p>
<%= pf.label :lastname %><br />
<%= pf.text_field :lastname %>
</p>
<% end %>
<p class="button"><%= f.submit %></p>
<% end %>
However,when I run this web application it shows error:
Can't mass-assign protected attributes: profile
on debug I found the user has attributes as:
:email:abc#gmail.com
:password:secret
:profile
---:firstname:abc
---:lastname:xyz
so,instead of expected params[:profile_attributes] the view returning params[:profile]
leading to mass-assignment error.so what is going wrong?
Did you try
<%= f.fields_for :profile do |pf|%>
?
I am a newbie in ROR, so please help me with this.
I created a model named 'Customer' from rails console, in the database there is a table named 'Customers' and it has columns: id, name, address, gender, dob, credit_card, created_at and updated_at. So, to save these information I created a view such as:
<%= form_for(#customer) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :dob %><br />
<%= f.date_select :dob %>
</div>
<div class="field">
<%= f.label :gender %><br />
<%= f.text_field :gender %>
</div>
<div class="field">
<%= f.label :address %><br />
<%= f.text_field :address %>
</div>
<div class="field">
<%= f.label :phone_number %><br />
<%= f.text_field :phone_number %>
</div>
<div class="field">
<%= f.label :credit_card %><br />
<%= f.text_field :credit_card %>
</div>
<div class="actions">
<%= f.submit 'Order', :action => :save_order %>
</div>
this view would be called by 'public' controller, from action 'check_out'
the code for action check_out is as:
def check_out
#customer = Customer.new
end
and code for action 'save_order' would be:
def save_order
#customer = Customer.new(params[:customer])
if #customer.save
#somcode
end
end
but i am getting a problem in the view part, "undefined method `customers_path' for #<#:0x9f49814>" in the line which contains "form_for(#customer)"
what i am doing wrong ? I am using rails 3.2.2
Thanks in advance :)
You don't have route for customer controller actions. Just add this line to routes.rb file
resources :customers
This one will generate several helpers, one of them will be customers_path. You can list all path helpers by command
rake routes
I don't understand how access data from my View in other table.
I have few models. First is User, second is UsersPreferences. So i have settings page for users and code looks like this:
<%= render 'shared/error_messages', :object => f.object %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
...
<div class="checkbox">
<%= f.check_box :notification_about_new_followers %>
<%= f.label 'Notify via email about new followers' %><br />
</div>
This code works (User has row notification_about_new_followers) but i want to change it. I decided that better way is keep preferences in other table. So i created model UsersPreferences which has user_id and flag 'notify_about_new_followers'. I tried to rewrite my view like that:
<%= render 'shared/error_messages', :object => f.object %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
...
<div class="checkbox">
<%= f.check_box UsersPreferences.find_by_user_id(#user.id).notify_about_new_followers %>
<%= f.label 'Notify via email about new followers' %><br />
</div>
But when i visit page with code i get such error
undefined method `true' for #<User:0x007f8ac180dee8>
How can i solve this error?
User model:
class User < ActiveRecord::Base
attr_accessible :name, ... , :notification_about_new_followers
...
has_one :users_preferences
end
UsersPreferences model:
class UsersPreferences < ActiveRecord::Base
belongs_to :user, :class_name => "User"
attr_accessible :notify_about_new_followers
end
This line:
<%= f.check_box UsersPreferences.find_by_user_id(#user.id).notify_about_new_followers %>
is causing the error. UsersPreferences.find_by_user_id(#user.id).notify_about_new_followers is true, so essentially that line reads:
<%= f.check_box true %>
And like the error says, there is no 'true' attribute for your UserPreferences model.
To fix this you'll need to first read up on MVC (Model-View-Controller). Without knowing how MVC works, you'll never be able to move forward with Rails. There are a lot of great resources out there, just google "Model View Controller for rails". Here is a good one. A little goofy, though... if that's not your style, try another link.
After you have learned that, look up the rails helper fields_for, and there you will find your answer.
i have model users, type_users and details_users. an users may have many type_users and type_users may have many users. user's form is:
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :last_name %>
<%= f.text_field :last_name %>
</div>
<div class="field">
<% for type_user in TypeUser.all %>
<div>
<%= check_box_tag "typeuser[typeuser_ids][]", typeuser.id %>
<%= typeuser.name %>
</div>
<% end %>
</div>
my question is:
how can i save the user(table users) and the types of users(table type_users) selected, saving the user in one table(table users), and the type of user(table details_users) on another table ?
I supose you have user_id and typeuser_id fields in your DetailsUser table so
In the user controller in action create after "if #user.save"do this
if #user.save
typeusers = params[:typeuser][:typeuser_ids]
length = typeusers.length
length.times.with_index do |i|
DetailsUser.create(:user_id => #user.id, :typeuser_id => typeusers[i])
end