Reputation: 819
In my Ruby on Rails application I am trying to add in validations that will ensure the user has entered a value in a text box. In my system I have a table called Account
which stores users' email account information, when they go onto the views/accounts/_form.html.erb
page to add a new email account I want to validate the presence of a port number. I can do this through the following code:
validates :port, presence: true
This successfully ensures that users enter their port number, but when a user signs up through the views/users/_new.html.erb
page they have to enter only an email address (e.g [email protected]) and the users_controller
will then create a record in the Account
table for this email address. My problem is that on the views/accounts/_form.html.erb
page the port number is required but on the views/users/_new.html.erb
it is not.
Is there a way of validating that the user enters the port number if they are on the views/accounts/_form.html.erb
page or invoking the create
method in the accounts_controller
?
I am aware that I could do this through the HTML required validation like so: <%= f.text_field :port, :required => true %>
but I need to add in further validation as well as presence, so this is not suitable.
Upvotes: 0
Views: 1278
Reputation: 164
I would not recommend you have model
aware of views
. In @SteveTurczyn 's solution, an abstract field is introduced into model to identified the which page it come from, which is an good solution.
As from Ruby on Rail MVC, both View
and Model
talk to the controller, another solution will be have controller handle validation of params before passing the value to create account
.
Upvotes: 0
Reputation: 7301
Extract that part of the logic into a form object, check out the legendary 2012 blog entry from CodeClimate. Things have changed since then, the author uses Virtus
to build form objects, more popular & up-to-date gems these days are:
if it's a one-off thing, just do what Steve said in the other answer but that is a sure way to hell, safe-hate and divorce (at least from personal experience) in any slightly teeny weeny bigger project (i.e. you mean to spend some hours more working on it, it's not like you just finished everything and want to go home).
Actually, just use form classes everywhere and avoid model validations & other callbacks at all. You don't want things sending account activation mails or validating your password complexity when you're writing tests and just need a "post" that belongs to "user".
My own favorite personal fuckup due to model callbacks is sending 240.000 "your account has been upgraded/downgraded" emails because of an innocent spelling change update in an account_type
attribute migration just because account_type_changed?
was true.
So.. Form classes for ever, model callbacks never.
Upvotes: 1
Reputation: 36860
You can create an attr_accessor
field that determines if the validation should occur...
class Account < ActiveRecord:Base
attr_accessor :port_needs_validation
validates :port, presence: true, if: -> {port_needs_validation}
Then just set the accessor in your create method...
def create
@account = Account.new
@account.assign_attributes(account_params)
@account.port_needs_validation = true
if @account.save
...
Upvotes: 7