rails 3 - if form field blank make value this instead - ruby-on-rails

I have a model called Post in my Rails 3 app.
Users can create their own urls for these posts. (I call this a clean_url.)
If the user does not complete this field, I want to create the value myself from the title upon saving the form. (Essentially use the #post.title.to_s(some reg ex to remove spaces etc...)
What is the best approach to having the item save with title value in this field if it is left blank?
I assumed in the Posts controller create action I could "update_attributes" of the post upon saving... but Im beginning to think maybe this is wrong?
Anyone have ideas on how to achieve this?

Use a before_save callback, and a private method in your model. The following is taken straight from my blog source.
before_save :create_clean_url
private
def create_clean_url
if self.clean_url.blank?
# Remove non-alpha characters. Replace spaces with hyphens.
self.clean_url = self.title.downcase.gsub(/[^(a-z0-9)^\s]/, '').gsub(/\s/, '-')
end
end

Related

Rails to_param - Without ID

I want to create param /users/will-smith, so here's my code:
def to_param
"#{full_name.parameterize}"
end
Parameterize will convert "Will Smith" to "will-smith"
So in the controller, the param won't match the find statement, thus return nil
# User with full_name "will-smith" not found
#user = User.find_by_full_name(params[:id])
Most of the solutions I found is by changing the param to #{id}-#{full_name.parameterize}. But I don't want the URL to contain the ID.
The other solutions is adding permalink column in the database, which I don't really like.
Any other solution?
Thanks
Here's a gem called FriendlyId. It will give you more options to play with.
The problem with your code is that you need to convert that parameter back to original, or use the same kind of transformation on your column during the search. FriendlyId, basically, helps you to achieve the same effect.
Also, I'm not sure, but you could miss that gist. It contaits lots of info on the topic.

Rails set the value of a field based on another field in the same record via Model

I have a table called Contacts. Two of it's columns are called email and maxname. When the Contact is created, I would to set maxname the the text before the # in the email field. So, if a new Contact is jebb#gmail.com, then his maxname should be jebb.
Just for testing I'm trying to put the whole email into maxname (before I figure out how to parse the email text).
So, in the Contacts Model I put this code:
before_create :set_maxname
before_update :set_maxname
protected
def set_maxname
self.maxname = self.email
end
That works. But, how can I parse the self.email so I just get the part before the # ??
Thanks for the help!!
Off the top of my head, doing self.email.split('#')[0] would work.
Edit: Also, the self isn't really necessary in this example. It's explicit, but not required.
Or you could use,
self.email.gsub(/#.*/,'')

How to add parameters to a ruby on rails post?

Say I have a model called User that has the following parameters: favorite_color, favorite_animal, and lucky_number. The user fills in the form containing only favorite_color and favorite_animal. When the form is submitted, I want to run a function that takes the color and animal into account and comes up with a lucky_number. How do I insert a value to the post values without the user filling out the form - how and where do I implement this?
Thank you!
Since the lucky_number won't be known until after the favorite_animal and favorite_color are already recorded, it would be impossible to send it along with the post request. Try using a
before_validation_on_create
that looks something like this:
before_validation_on_create :generate_lucky_number
def generate_lucky_number
self.lucky_number = self.favorite_animal.length + self.favorite_color.length
end
This function just sets the lucky number to the combined length of the strings stored for the favorite color and favorite animal, and will set it before saving the user to the database.
You could build it into your controller logic, or place the code in your model in one of the following callbacks:
before_validation
before_validation_on_create
before_validation_on_update

validating a math equation with rails validation

I want the sign up form on my site to have a field that takes the sum of a math equation and use rails validation to validate it. Whats the best way to do it?
i.e
What is 6 + 9 ? [ 8 ]
Error Message : You have entered the wrong number
Override the validate method in your model class. Remember that the model object you create for the new action is a different instance than the one created for the create action, so you'll need to save the random seed or the math expression somewhere in your form so that you can recreate it during validation.
Then, something along the lines of:
def validate
unless math_equation_answered?
errors.add("math_answer", "is incorrect")
end
end
The implementation of math_equation_answered? is up to you, and math_answer should be changed to whatever model field you use for the user's answer.

What's the best way to validate multiple emails and handle errors in Rails?

In the current app I'm building I've got a textarea where a user will enter a comma-delimited list of email addresses.
I'm currently splitting the list into an array and then saving one by one. But if, say, I have this input...
blah#example.com, test#example, foo#example.com
... then blah#example.com will be saved, but saving test#example will fail. So I then need to remove blah#example.com from the comma-delimited string of values that I pass back to the textarea when I show the error that test#example isn't a valid email address.
Is there a better way to validate these on the server side and handle errors without getting fancy / ugly in the controller?
Thanks in Advance!
Assuming this is a model that has_many emails, and the email model uses :validate_email, you could do something like the following:
class Foo < ActiveRecord::Base
validate :must_not_have_invalid_addresses
...
def emails=(addresses)
#invalid_addresses = []
addresses.split(",").each do |address|
#invalid_addresses.push(address) unless emails.create({:address => address})
end
end
def must_not_have_invalid_addresses
errors.add_to_base("Some email addresses were invalid") unless #invalid_addresses.empty?
end
end
This provides a validation error + an array of the invalid email addresses which you can make accessible to your view if you like.
ruby has a split function (.each) described here and supports regular expressions as described here
as such, you'd split the string (using "," as your separator) and then use the regular expression to validate each e-mail.
You can put saving emails in transaction. Then if any save will fail, then all previos saves are canceled. In such case, validations can be done only on model layer.
I think it would be clear code, but for sure it isn't the fastest possible way (but using Ruby means you are not doing it in even fast way ;) )
If you have them in a variable called emails, perhaps something like this may work:
if valid_emails?(emails)
# then have your normal logic here
if #user.save
flash[:notice] .....
end
end
private
def valid_emails?(emails)
not emails.find {|email| email =~ /[\w\.%\+\-]+#(?:[A-Z0-9\-]+\.)+(?:[A-Z]{2,}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|jobs|museum)/i }.nil?
end
EDIT: actually you may just want to use this regular expression. It was taken from the restful-authentication plugin.

Resources