Generate URL based on title in rails 3 - ruby-on-rails-3

I am new to Rails. Please help. I have 2 fields in model
class Article < ActiveRecord::Base
attr_accessible :title, :url, :description
end
After user enters the title, we need to auto populate the url form field by changing the following in title
remove all special characters from title
replace spaces with dash "-"
downcase
Then user can update the url to customize it further. Finally, when he clicks on "Create Article" button, we need to check the above 3 conditions again to validate.
I am using Rails 3.2.6
Thank you.

I assume that its a web app and the user is give a form with two textboxes where he can enter the title and url.
You can use javascript to auto generate the url in the textbox, where user can customize it and save.

Related

Rails 3 - Create record on tick of a checkbox

In Rails 3.2 , how do you create multiple records on tick of a check box ?
In my view I use as
= check_box_tag 'product[product_ids][]', product.id
I checked the development logs and the checkbox values are as
"product"=>{"product_ids"=>["193", "195"]}
And in the controller I do something as
#cpr = CouponProductRestriction.new(params[:product])
#cpr.save
But I get an error as
Can't mass-assign protected attributes: product_ids
Is there something I am doing wrong ?
The error message indicates it is not the problem of the checkbox. You just need to add an attr_accessible declaration. In other words add the following line in the Product model:
attr_accessible :product_ids

Add after_save callback for tag gem model to update tire index

I have a posting model that has tags using the rocket_tag gem
class Posting < ActiveRecord::Base
attr_taggable :tags
def tag_list
self.tags.join(",")
end
def tag_list=(new_tags)
attribute_will_change!(:tag_list)
# split into array (comma and any spaces), ignore empties
self.tags = new_tags.split(/,[\s]*/).reject(&:empty?)
end
It seems to work fine in my dev environment but when I use FactoryGirl to generate a posting for tests it doesn't seem to add the tags to the search index so I assume these are getting saved after the posting and so when the search index gets updated it doesn't see any saved tags so they are not searchable using tire.
I assume this means that I need to add an after_save callback to the rocket_tag Tag model to call touch() against the posting model but I'm not sure how to extend the model from the gem to add this extra callback and method to it.....unless something from the above could be at fault.
FactoryGirl.define do
factory :posting do
sequence(:name) { |m| "Posting #{m} name" }
tag_list "tag,another,third"
user
end
end
Not sure why it doesn't work but in the end I used FactoryGirl.create to create the posting, visited the edit page for the posting, used capybara's fill_in to add the tags, click_button "Submit" and then I refreshed the search index.
ie I added the tags in the same way a normal webpage user would rather than trying to use FactoryGirl to set them.

Value empty in password text box rails 3?

<%=password_field 'email_setting','emailpasswd' %>
In this #email_setting.emailpasswd has the value password(#email_setting.emailpasswd="password").
But in email_setting form edit the password text box is loaded with empty.Instead of that I need to show some characters(#######) to indicate that the password is already entered.
I'm using Rails 3.
You could also do something like this:
In /config/initializers/my_constants.rb, set a constant with the value that you'd like to display to the user in the password input box.
STARS_PASSWORD = '*******'
In the User model, create a method that we will call from the form to determine what to display to the user inside the password input box.
class User < ActiveRecord::Base
def password_form_value
password.present? ? STARS_PASSWORD : ''
end
end
In the form, display the STARS_PASSWORD as the value on the input form, if in fact the user has already set a password.
<%=form.password_field :password, :value => #user.password_form_value %>
In the UsersController, delete the submitted password before updating if the submitted password is STARS_PASSWORD.
params[:user].delete :password if params[:user][:password] == STARS_PASSWORD
NB: If you have a password validator on the User model (for example, the password needs to have letters and numbers), you will also need to modify that validator to allow STARS_PASSWORD.
This is a security precaution of Rails that password fields are not prepopulated. Otherwise they would be visible in plain text in page source.
If you really want to display it there though, you need to bypass form helpers and fallback to plain HTML:
<input type="password" name="email_setting[emailpasswd]" value="<%= #email_setting.emailpasswd %>" />
However that will not work well if you have your passwords hashed. You can't "decrypt" a hashed password, so you can't show them in plain text here.
password_field renders with nil value by default. This makes the use of passwords secure by default. If you want to render the value of the password_field, you have to do for instance
f.password_field(:password, :value => #user.password)
https://github.com/rails/rails/commit/1851af84c1c7244dc416be9c93a4700b70e801e3

Rails - How to include a hyperlink in a text field

I have a notices model which contains records of notices for each user. Each notice record contains a message which is a text field with the notice message. These messages look like:
"#{current_user.username} liked your photo '#{#photo.name}."
In the example above, I would like the user and the photo to also be hyperlinks to that user and photo.
Here is a snippet from my likes_controller which generates a notice when a new like is created:
class LikesController < ApplicationController
def create
#photo = Photo.find(params[:id])
#like = Like.new(:photo_id => #photo.id, :user_id => current_user.id)
if #like.save
#notice = Notice.new(:user_id => #photo.user_id, :message => "#{current_user.username} liked your photo '#{#photo.name}'
end
Any thoughts on how I can include links in the message; is this even possible? Thanks.
Adding a link to your message is a rendering issue. In my opinion, you're rendering the message too soon, I would render it in the view.
If you change your Notice model so that it contains a the user_id and the like_id, you can render the notice text in the view (which also lets you localize the text later, should it prove necessary).
Rendering in the view lets you use the standard link_to helper to generate your links.

How to user defined friendly URLs in Rails 3?

Now i have something like this
http://myapp.com/pages/1
http://myapp.com/pages/2
http://myapp.com/pages/3
http://myapp.com/pages/4
And each page belong to one user
What i need is to each user to set it's own custom name for the page.
I was thinking of using the friendly_id gem http://norman.github.com/friendly_id/
but I don't find any method to directly edit the slug to set a custom friendly url
how should i proceed?
FriendlyID is a great gem.
It shouldn't be hard to implement user defined page URL.
Create table pages with user_id and link
class User < ActiveRecord::Base
has_many :pages
class Page < ActiveRecord::Base
belongs_to :user
has_friendly_id :link # link is name of the column whose value will be replaced by slugged value
On the page#new you add an input for the link attribute.
Alternatively, you could set friendly_id on title or something else with :use_slug => true option. This way FriendlyID will take the title and modify it so it doesn't have and restricted characters. It will use it's own table to store slugs. Use cached_slug to increase performanse.
Updated
To give users a choice whether they wan't to set a custom link, you could do this:
Set friendly_id on the link field without slugs..
Make a virtual attribute permalink so you could show it in your forms.
In the before_filter, check whether the permalink is set.
If it is, write it to the link field.
If it's not, write title to the link field.
FriendlyID uses babosa gem to generate slugs. If you decide to use it as well, this is how your filter could look like:
protected
def generate_link
#you might need to use .nil? instead
self.link = self.permalink.empty? ? make_slug(self.title) : make_slug(self.permalink)
end
def make_slug(value)
value.to_slug.normalize.to_s #you could as well use ph6py's way
end
Adding to_param method to one of the models should help:
def to_param
"#{id}-#{call_to_method_that_returns_custom_name.parameterize}"
end
Hope this is what you are looking for :)
I am not using the friendly_url gem and am not sure whether my way is efficient. But it works fine for me.
I have a model called Node with id and friendly url field called url_title.
My routes.rb file:
resource 'nodes/:url_title', :to => 'Nodes#view'
nodes_controller.rb
class NodesController <ActiveController
def view
#node = Node.find_by_url_title(:params(url_title))
end
end
And use the #node variable to populate your view.
Now, whenever I type www.example.com/nodes/awesome-title , it takes me to the proper page. One argument against this can be need to create an index on a non-primary field. But I think that might be required for better performance even in the friendly_url gem. Also, the non-primary field url_title needs to be unique. Again, this might be required even for correct working for friendly_url .
Feel free to correct me if I am wrong in these assumptions.
There are a variety of ways, you can achieve this-
1) using Stringex
2) sluggable-finder
3) friendly_id
A complete step by step methodology with reasons for each to be used can be found out here. Happy reading!