I'm using Devise in a Rails app and need to pass an extra field (possibly) when the user logs in. If the user logs in through a subdomain, everything works. If they come in without a subdomain, I'd like for them to be required to put it into a text box. The subdomain isn't part of the user model, it's part of the organization (company). Here's the view
```
<div class="row">
<%= f.email_field :email, :class => "input_text", :placeholder=> "Email" %>
</div>
<div class="row">
<%= f.password_field :password, :class => "input_text", :placeholder=> "Password" %>
</div>
<% if request.subdomain.blank? %>
<div class="row">
<%= f.text_field :subdomain, :class => "input_text", :placeholder=> "Organization" %>
</div>
<% end %>
```
Here's the relevant parts of the user model ...
```
devise :token_authenticatable, :database_authenticatable, :recoverable, :rememberable, :trackable, :lockable,
:authentication_keys => [:email], :request_keys => [:subdomain]
def self.find_for_authentication(conditions={})
conditions[:organization_id] = Organization.find_by_subdomain(conditions[:subdomain]).id
conditions.delete(:subdomain)
super(conditions)
end
```
I end up with subdomain being undefined for a nil class in the view.
Any ideas on how to make this work?
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
Can anybody resolve my one issue.I want to save all of my values in sqlite database.I have name,emailid and password field.when i clicked on submit button only name and email-id has stored in database bit i found that password filed is showing blank.I am using rails version-4.0.2 and ruby 1.9.3.The codes are given below.
views/users/index.html.erb:
<h1>This is index page</h1>
<center>
<p>Enter data</p>
<div class="option">
<p><%= link_to "Click here to enter data",users_new_path %></p>
<p><%= link_to "Display data",users_display_path%></p>
</div>
</center>
views/users/new.html.erb:
<h1>Enter your data here</h1>
<center>
<%= form_for #user ,:url => {:action => "create"} do |f| %>
<div class="div_reg">
<p>
<label for="username" class="uname" data-icon="u" >username </label>
<%= f.text_field:name,placeholder:"Enter your user name" %>
</p>
<p>
<label for="username" class="uname" data-icon="u" >Email </label>
<%= f.text_field:email,placeholder:"enter your email" %>
</p>
<p>
<label for="username" class="uname" data-icon="u" >Password </label>
<%= f.password_field:password,placeholder:"Enteryour password" %>
</p>
<center>
<%= f.submit "Submit",:class => 'btn-custom' %>
</center>
<div class="back_btn">
<button type="button" class="btn-custom " style="cursor:pointer;">Back</button>
</div>
</div>
<% end %>
</center>
<% if #user.errors.any? %>
<ul class="Signup_Errors">
<% for message_error in #user.errors.full_messages %>
<li><%= message_error %></li>
<% end %>
</ul>
<% end %>
controller/users_controller.rb:
class UsersController < ApplicationController
def index
end
def new
#user=User.new
end
def create
#user=User.new(users_param);
if #user.save
flash[:notice]="You signed up successfully"
flash[:color]="valid"
redirect_to :action => 'index'
else
flash[:alert]="You have not signed up successfully"
flash[:color]="invalid"
redirect_to :action => 'new'
end
end
private
def users_param
params.require(:user).permit(:name, :email, :password)
end
def display
end
end
model/user.rb:
class User < ActiveRecord::Base
attr_accessor :password
EMAIL_REGEX = /\A[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}\z/i
validates :name, :presence => true, :uniqueness => true, :length => { :in => 3..20 }
validates :email, :presence => true, :uniqueness => true, :format => EMAIL_REGEX
validates :password, :confirmation => true
validates_length_of :password, :in => 6..20, :on => :create
end
migrate\20150102052336_create_users.rb
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :email
t.string :password
t.timestamps null: false
end
end
end
Please help me to resolve this issue.Thanks in advance.
You should add a password_confirmation field
<%= f.password_field :password %>
<%= f.password_field> :password_confirmation %>
add also add it into the permitted parameters
params.require(:user).permit(:name, :email, :password, :password_confirmation)
PS: I recommend looking up devise gem, once you figured how to create your own signup/login implementation..
I am making a polymorphic association with devise and simple for but for some reason i cant get the params to work
here is my code:
User:
class User < ActiveRecord::Base
devise :database_authenticatable,
:rememberable, :trackable, :validatable
belongs_to :loginable, polymorphic: true
end
Designer:
class Designer < ActiveRecord::Base
has_one :user, as: :loginable
accepts_nested_attributes_for :user
end
Layout:
<%= simple_form_for [:admin, #designer] , :html => { :class => 'form-horizontal' } do |f| %>
<% if f.error_notification %>
<div class="alert alert-error fade in">
<a class="close" data-dismiss="alert" href="#">×</a>
<%= f.error_notification %>
<% if #designer.errors.any? %>
<ul>
<% #designer.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
</div>
<% end %>
<div class="control-group">
<%= f.label :profile_name, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :profile_name, :class => 'text_field' %>
</div>
</div>
<%= f.simple_fields_for users do |u| %>
<div class="control-group">
<%= u.label :email, :class => 'control-label' %>
<div class="controls">
<%= u.text_field :email, :class => 'text_field' %>
</div>
</div>
<div class="control-group">
<%= u.label :password, :class => 'control-label' %>
<div class="controls">
<%= u.password_field :password, :class => 'text_field' %>
</div>
</div>
<div class="control-group">
<%= u.label :type, :class => 'control-label' %>
<div class="controls">
<%= u.input :role, :label => false do %>
<%= u.select :role_id, Role.all.map { |r| [r.name, r.id] } %>
<% end %>
</div>
</div>
<div class="control-group">
<%= u.label :firstname, :class => 'control-label' %>
<div class="controls">
<%= u.text_field :firstname, :class => 'text_field' %>
</div>
</div>
<% end %>
<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
</div>
<% end %>
Controller:
def create
#user = User.new(designer_params)
#designer = Designer.new(designer_params)
#user.loginable = #designer
respond_to do |format|
if #user.save! && #designer.save!
format.html { redirect_to admin_designers_path, notice: 'Designer was successfully created.' }
format.json { render action: 'show', status: :created, location: admin_designer_path(#designer) }
else
format.html { render action: 'new' }
format.json { render json: [designer: #designer.errors, user: #user.errors], status: :unprocessable_entity }
end
end
end
def designer_params
params.permit(:profile_name, :user, user_attributes: [:email, :password, :password, :firstname, :lastname, :address, :postalcode, :city, :country, :role, :role_id])
end
My params seems to ignore the user attributes, i only see profile name for some reason.
Any ideas on how to fix this would be greatly appreciated
Thanks!
I managed to resolve my own issues. so i am posting the answer hoping to save someone else lots of time.
i ended up creating another private method for the user params
def designer_params
params.require(:designer).permit(:profile_name, user_attributes: [:email, :password, :password, :firstname, :lastname, :address, :postalcode, :city, :country, :role, :role_id])
end
def user_params
params[:designer][:user_attributes].permit(:email, :password, :password, :firstname, :lastname, :address, :postalcode, :city, :country, :role, :role_id)
end
and then using those to create my relationship
def create
#designer = Designer.new(designer_params)
#user = User.new(user_params)
#user.loginable = #designer
#designer.save!
end
also if you are having trouble viewing the nested form make sure to use the
build_ method
def new
#designer = Designer.new
#user = #designer.build_user
end
I an struggling with the syntax of the controller for nested models. There are many other questions out there but i am not having any luck and i have reached my 2 day struggling threshold, so its time to ask!
I have 3 Models, User, Farm, Product. - User has_many Farms, Farm has_many Products.
On the user show page i display a list of farm/s created by the user in a partial...
#users_controller
def show
#user = User.find(params[:id])
#farms = #user.farms
end
#show.html.erb
<% if #user.farms.any? %>
<center><h4>My Farms(<%= #user.farms.count %>)</h4></center>
<hr>
<%= render #farms %>
This works as expected.
What i would like to do is display all the products of the farm, within the _farm partial, as a list. However I dont know what to add to the controller? Adding
#products = Product.find(params[:id])
obviously displays all products, not just one made by that farm. So how to i create the controller code and/or the partial code to only show the products created by that particular farm?
I was thinking along the lines of...
#products = Product.find(params[:farm_id])
but it does not work and seems to simple!
I obviously need to pass a key somewhere to the partial within the partial, but i have no idea how to do it!
Any Help will be massively appreciated...its driving me nuts!
Many thanks, Alex
EDIT ::
#product.rb
class Product < ActiveRecord::Base
attr_accessible :description, :farm_id, :name, :ammount, :price, :category, :pic, :longitude,
:latitude, :image
belongs_to :farm
mount_uploader :image, ImageUploader
#farm.rb
class Farm < ActiveRecord::Base
attr_accessible :content, :name, :user_id, :description, :street_name, :bldg_name, :region, :post_code,
:province, :contact_number, :swap, :organic, :deliver, :image, :products_attributes
belongs_to :user
has_many :products
acts_as_followable
validates :user_id, presence: true
accepts_nested_attributes_for :products
mount_uploader :image, ImageUploader
#user.rb
class User < ActiveRecord::Base
mount_uploader :avatar, ImageUploader
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :confirmable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :region,
:description, :avatar, :street_name, :bldg_name, :post_code, :province, :contact_number, :avatar,
:avatar_cache, :remove_avatar, :products_attributes, :product
# attr_accessible :title, :body
acts_as_follower
has_many :farms
has_many :swaps
has_many :products, :through => :farms
# validates_presence_of :image
# validates_integrity_of :image
# validates_processing_of :image
has_private_messages
EDIT 2 ::
#_products.html.erb
<hr>
<div class="row-fluid">
<div class="span3"> <%= image_tag product.image_url(:thumb) %> </div>
<div class="span5">
<h2><%= product.name %></h2>
<table>
<tr>
<td><strong>Ammount Available ::</strong></td>
<td><center><%= product.ammount %></center></td>
<td><strong>Kilos</strong></td>
</tr>
<tr>
<td><strong>Price/Kilo ::</strong></td>
<td><center><%= product.price %></center></td>
<td><strong>Euros</strong></td>
</tr></table>
</div>
<br><br><br>
<div class="span3">
<%= link_to "View Product", product, class: "btn btn-small btn-secondary" %>
<% if correct_user?(#user) %>
<%= link_to "delete", product, class: "btn btn-small btn-secondary", method: :delete, confirm: "You sure?" %><% end %>
</div>
-
#_farm.html.erb
<div class="<%= cycle("even", "odd") %>">
<div class="container">
<div class="row-fluid">
<div class="span2">
<%= image_tag farm.image_url %>
</div>
<div class="span2">
<%= farm.name %>
</div>
<div class="span4">
<span><%= " Location :: " %><%= farm.user.region %></span><br>
<span><%= " Can it be delivered :: " %><%= farm.deliver ? 'No' : 'Yes' %></span><br>
<span><%= " Is it Organic :: " %><%= farm.organic ? 'Yes' : 'No' %></span><br>
<span class="timestamp">Listed on <%= farm.created_at.strftime("%d %b. %Y") %> </span>
</div>
<div class="span4">
<br>
<br>
<br>
<%= link_to 'Sell A Product', new_farm_product_path(farm), class: "btn btn-small btn-secondary" %>
<%= link_to 'Edit Grow Spot', farm, class: "btn btn-small btn-secondary" %>
</div>
</div><!-- end container -->
</div>
<div class="row-fluid">
<div class="span2"></div>
<div class="span8">
<% for product in farm.products do %>
<%= render :partial => "product", :product => product %>
<% end %>
</div>
<div class="span2"></div>
Using <%= render #farms %> in a view means you must have a partial called _farm.html.erb in app/views/farms
in that partial you can use farm variable:
<% for product in farm.products do %>
<%= product.name %>
<%= product.price %>
....
<% end %>
no need to add something in controller.
update
<% for product in farm.products do %>
<%= render :partial => "product", :locals => { :product => product } %>
<% end %>
in app/views/farms/_product.html.erb
<div class="zzz">
<div><%= product.price %></div>
</div>
Hello Im using devise to register users, and I want to create a profile related to a user every time a user signs up, the problem is that when I try to add the full name of the person from the profile model on the registration view for devise's user registration, it does not show up...
This are my models:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :profile_attributes
has_one :profile, dependent: :destroy
accepts_nested_attributes_for :profile
# attr_accessible :title, :body
end
This is the profile model
class Profile < ActiveRecord::Base
attr_accessible :email, :name, :phone, :code
belongs_to :user
validates_presence_of :user
end
And this is the devise view modified:
<% provide(:title, 'Sign up' ) %>
<h2>Sign up</h2>
<div class="row">
<div class="span6 offset3">
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= render 'shared/error_messages', object: resource %>
<%= f.fields_for :profile do |profile_form| %>
<%= profile_form.label :full_name %>
<%= profile_form.text_field :name %>
<% end %>
<%= f.label :email %>
<%= f.email_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
<div class="form-actions">
<%= f.submit "Sign up", class: "btn btn-large btn-primary" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>
</div>
I cant see anything wrong to why the name text field would not appear...
Thank you for your help
Figured it out, it was so simple I feel bad... so here it is:
I forgot to generate a new profile on the form so it ends up looking kind of like this:
.
.
.
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= render 'shared/error_messages', object: resource %>
<div class="invisible">
<%= resource.build_profile %>
</div>
<%= f.fields_for :profile do |profile_form| %>
<%= profile_form.label :full_name %>
<%= profile_form.text_field :name %>
<% end %>
<%= f.label :email %>
<%= f.email_field :email %>
.
.
.
Hope this solves someone else's problem as well!
Thank you!
This question is already answered, but I thought I'd throw this up as an alternative for others. Form backing objects can be used to go back to a one form/one model kind of setup and help keep code cleaner.
Here's a good writeup on it:
http://pivotallabs.com/form-backing-objects-for-fun-and-profit/