Basically I have an app(using devise), where a user signs up registrations#new
with just an email and password; this registers and creates the user. It immediately takes them to registrations#edit
where they enter the rest of their information.
I am using a :name
attribute with friendly_id for vanity urls. This attribute has 3 requirements:
For #2 So I added the following validation to my model: `
validates :name, :exclusion => { :in => %w(
admin cars registrations users
), :message => "Sorry \"%{value}\" is taken!"}`
For #3
I added
validates_uniqueness_of :name
For #1 I have the following in my view under registrations#edit:
<% if @user.name.blank?%>
<br>
<h2>Choose your username</h2>
<%= f.input :name, :value => "Username" , required: true, autofocus: true, label:false, class: 'usernameinputc' %>
<br>
This effectively hides it from the user if it doesn't exist. The problem I am having is that if they enter a controller name as their :name
or something already taken it will give a devise error, and send them back but the field will be hidden. If i remove the conditional then it allows them to change their :name
even if it was valid? How can i make it so it shows only if the name attribute hasn't saved?
Note: I tried if @user.name.persisted?
it gave me a no method error for nilClass(I think because :name
didn't exist.
So I have tried to add it as a virtual attribute, I have added a field :username to my permitted params as a virtual attribute. Having a little bit of trouble with the getter and setter methods. I tried this:
def username
self.name if self.name.persisted?
end
I still get a no method error.
What if you try this? This will validate your name against the black list, but also sets the user.name to blank when this happens. This way your erb will still render correctly.
validate do |user|
if %w(admin cars registrations users).include?(user.name)
user.errors[:name] << "Sorry \"" + user.name + "\" is taken!"
user.name = ""
end
end