In my create action in the comments controller I want to check if the comment text contains a "# + username" so I can add it to my public activities.
if #comment.body.include?(' [HERE] ')
maybe User.all.username.any? ?
You better use ruby regex to first find the user name from comment body matching pattern #abc and then user that username query database to find user
#comment.body.scan(/#(\w+)/).flatten.to_a.each do|username|
if User.where(:username => username).any?
# your code here
end
end
or search the users with single database query by passing the array
usernames = #comment.body.scan(/#(\w+)/).flatten.to_a
if User.where(:username => usernames).any?
# your code here
end
This will optimize the db query and will not load all users to memory.
A quick answer:
if User.pluck(:username).any? {|u| #comment.body.include?("##{u}")}
# ...
end
A better answer:
Why not use a javascript library to auto-complete the username? This is more user friendly, and scales better as the User table grows.
Related
I can't use any of the gems for creating clean Urls in rails. Instead I am rolling out my own implementation. I have created the following entry in routes.rb
match "/:slug" => "cleanurls#index"
Where cleanurl is a controller for handling all such requests. In the cleanurl controller:
class CleanurlsController < ApplicationController
def index
slug = params['slug']
url = Url.where(:slug => slug).first
case(url.url_type)
when 'profile'
user_id = url.id.to_i
#profile = Profile_info.getProfileDetails(user_id)
render '/profiles/index'
end
end
end
I have created the table urls which stores the slug,id (as relevant) and the type of page. Right now I have only the profile page to deal with but in the future I will have different types of pages with clean urls.
My first Question:
1) Is this implementation the right approach? And is this okay from a performance perspective given the tables have all the right indexes.
I am making the profile url like this:
def self.makeProfileUrl(id,name)
name = name.strip.titleize
extension = User.where(:name => name).count - 1
slug = name.split(" ").join("-")
if extension != 0
slug += "-#{extension}"
end
Url.create(:slug => slug, :id => id.to_i, :url_type => 'profile')
end
I am using extension to append a count in case their are users who share the same name.
Question:
Is this the right way to create the slug and ensure it being unique? Fetching the count of a name from the other table does not seem right.
Answering the question #1:
I don't know the details of what's your overall goal, but if you'd like
to have such URLs that are based on records from the database - then yes: it's
a good approach.
Answering question #2 (regarding slugs):
I'd rather use something much more elaborate and well tested like:
https://github.com/norman/friendly_id
My 50 cents about some other things:
Is this one of your first projects in Ruby/Rails? If so - congratulations! :)
I'm asking because I noticed that you're using camel case here and there...
Also:
user_id = url.id.to_i
Why do you call this #to_i method here? Did you set up this id as a string
or something?
Hope this helps
There is already created record, like
Company "Life"
How to make this record to the species
сompany-life
I used parameterize, but it turns:
company-quot-life-quot
As I understand, .gsub(""", "") is not suitable for implementation, since to create too large list of exceptions
Is there may be a way to make record in raw format? (to parameterize later)
thanks in advance!
Here is a non-Rails approach:
require 'cgi'
str = 'Company "Life"'
puts CGI.unescape_html(str).gsub(/"/, '').gsub(/\s+/, '-').downcase
# => company-life
And a pure regex solution:
puts str.gsub(/&\w+;/, '').gsub(/\s+/, '-').downcase
# => company-life
And if you are inside Rails(thanks to #nzifnab):
str.gsub(/&\w+;/, '').parameterize
As #meager said, you shouldn't be storing the html-encoded entities in the database to begin with, how did it get in there with "? Theoretically this would work:
class Page < ActiveRecord::Base
before_validation :unescape_entities
private
def unescape_entities
self.name = CGI.unescape_html(name)
end
end
But I'm still curious how name would be getting there in the first place with html entities in it. What's your action/form look like?
"Company "Life"".html_safe.parameterize
"Company "Life"".gsub(/&[^;]+;/, "-").parameterize.downcase
# => "company-life"
Firstly, gsub gets rid of html entities, then parameterize gets rid from all but Ascii alphanumeric (and replaces them with dash), then downcase. Note that "_" will be preserved too, if you don't like them, another gsub('_', '-') is needed.
Hi people as all know rails by default put ids and names id=model_attribute and name=model[attribute].
My question is How I can get the default id or name from a Model o with I18n?
For example User.human_attribute_name 'password' give the Password label, well how i do to put
User.give_me_the_id_or_name 'password' and give 'user[password]' or 'user_password'
Thinks at advance ^^
Look at the source. http://github.com/rails/rails/blob/master/actionpack/lib/action_view/helpers/tags/base.rb
and build your own construction in your model class if you really want to. :)
def self.give_me_the_id_or_name(method)
result = "#{self.model_name.param_key}[#{method.to_s.sub(/\?$/,"")}]"
result.instance_eval do
def id
self.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
end
end
result
end
User.give_me_the_id_or_name(:password) ===> "user[password]"
User.give_me_the_id_or_name(:password).id ===> "user_password"
But I'm actually don't understand what you mean about I18n? These names used by default as tags titles when you rendering the model into tempate.
I used LinkedIn gem by pengwynn to get authentication from LinkedIn. Everything works fine, and I get a Mash in a callback that looks like this:
#<LinkedIn::Mash all=[#<LinkedIn::Mash company=#<LinkedIn::Mash id=1422 industry="Banking"
name="Company" size="10,001+ employees" ticker="ABC" type="Public Company"> id=2851554
is_current=true start_date=#<LinkedIn::Mash month=12 year=2008> summary="" title="Boss">] total=1>
How can I parse it to something similar to Rails params in order to create a new object from it?
Thank you.
When you receive list of connections of any sort from LinkedIn, you need to get to the list from all. On the object you received from LinkedIn, you have {all, total}. total will give you the number of objects in the array, all will give you all of the objects. So if you wanted to turn the first company into a hash, you would call object.all.first.to_hash. You can iterate through all of them by doing object.all.each {|c| # your block}.
If your own Rails models match the objects being returned from the linkedin gem, you can do:
companies.all.each do |company|
Company.create(company.to_hash)
end
If they don't map 1:1, you can just choose the fields you want:
companies.all.each do |company|
c = Company.new
c.name = company.name
c.year_founded = company.start_date.year
c.ticker = company.ticker
# etc. etc. etc.
c.save
end
You can just call .to_hash to turn a Mash into a Hash (like params).
Source:
https://github.com/intridea/hashie/blob/master/lib/hashie/hash.rb
I am developing an API in Rails 3.
Lately I have seen some user accounts being double. I am not sure how many so I need a way to find out which accounts that are double.
Is there a way, in ruby, to search the entire database and fetch those user accounts that got the same email address (hence double)?
Thankful for all input!
Just open the Rails console (rails c) and type something like this:
Account.group(:email).having('count_all > 1').count
This will return a Hash with email addresses being the key and the number of times it occured as the value. The result will look something like this:
=> #<OrderedHash {"billyjoe#example.com"=>2, "johndoe#example.com"=>2}>
Then, I guess you could take those email addresses and actually get the accounts:
Account.where(:email => "billyjoe#example.com")
To output them all in the console, you could combine both of those like this:
email_hash = Account.group(:email).having('count_all > 1').count
email_hash.each do |email, count|
Account.where(:email => email).each do |account|
p account
end
end
I think if you try to use(for example):
UserAccount.all.group_by(&:email_address).each do |email, record|
#you will get a set of records grouped by email address
end
this will help you (You did not write detailed description of your models but if think you will get the clue)