Using the attr_encryptor-2.0.0 gem with rails 3.2.11 to encrypt a text field in my postgresql 9.2.2 database.
class Task < ActiveRecord::Base
attr_encrypted :description, :key => 'A secret key'
Before encryption I used the following where-clause to find records with description containing a given search term s.
current_user.tasks.where("description like ? ", '%'+s+'%')
How can I do it with encrypted description column?
I don't get how the find_by_encrypted_<column> works. The code below returns nil whether I use the entire description or a substring (of an existing record) as search term s.
current_user.tasks.find_by_encrypted_description(Task.encrypt_description(s))
I haven't changed the way I create records after adding encryption. Should I?
t = current_user.tasks.build(:description => #description)
Thank you!
Ended up using attr_encrypted-1.2.1 gem and the following select clause:
tasks = current_user.tasks.select {|t| Task.decrypt(:description, t.encrypted_description).include?(s))}
With attr_encryptor-2.0.0 gem I was getting a bad decrypt error with the same code.
Related
I have the following Jbuilder setup but I'd like to output the 'uw_question_ids' as values only. No 'id:' key. Is this possible?
json.menu do
json.uw_question_ids menu.uw_questions do |uw_question|
json.(uw_question, :id)
end
end
Currently, the output JSON is...
"menu":{"uw_question_ids":[{"id":"17"}]}
I'd like it be...
"menu":{"uw_question_ids":[{"17"}]}
I figured it out... simple!
json.menu do
json.uw_question_ids product.uw_question_ids
end
I didn't realize that Rails gives you access to a 'collection_singular_ids' method (in my case, 'uw_question_ids') when you create has_many or has_and_belongs_to_many associations. That's what I needed.
How can I validate uniqueness of an attribute with a custom or virtual scope? I thought of using a virtual attribute, but it keeps trying to query audit_year in the database. I would rather not create another database column just for the purpose of this uniqueness constraint.
Each location can only have one audit scheduled per year, so I need to extract the year from the scheduled attribute and validate uniqueness over that scope.
class Audit
attr_accessible :location_name, :scheduled_date, :completion_date ...
validates :location_name, :presence => true, :uniqueness => { :scope => :audit_year }
...
def audit_year
scheduled_date.year
end
end
I may not even be on the correct path with my virtual attribute attempts. What would be the "right" way to do this in rails?
I know this is a bit late, but I figured I'd pitch in. I'm doing this from memory so you may need to screw with this a bit.
My first thought is in your audit_year method, you could query the database for all years. Something like:
def audit_year
!self.class.select('selected_date').map{ |a| a.selected_date.year }.include?(selected_date.year)
# or using Rails 3.2 and Ruby 1.9.3:
# !self.class.pluck('created_at').map(&:year).include?(selected_date.year)
end
My assumption of the unique method is if it returns false, it will fail validation. This code selects just that one column from your class (I used self.class instead of Audit so it's more reusable), then maps out the years to an array. If it's included (true), return the opposite (!). You could probably optimize the query with uniq, but it depends on how large the table is whether it's necessary or not.
The other option would be to roll your own validator for the attribute, which really wouldn't be that difficult. The only difference is you'd add a line that conditionally checks for selected_date.present? in addition to the above. A great resource is the Rails Guides for callbacks and errors if you don't know how: http://guides.rubyonrails.org/active_record_validations_callbacks.html
Hope that helps.
I have the following in my model to search for a string entered by a user:
def self.find_products(product="")
find(:all, :select => 'product_id, name', :order => "name", :conditions => ["name like ? and locale =?", "%#{product.capitalize}%", I18n.locale])
end
But it only works if the string is one word.
If the string contains two or more words such as "card guides" it returns nothing even if those are the exact words in the name.
How can I do this search properly.
Rails 3 Ruby 1.9.2
Update
It turns out that its a Postgresql syntax. I needed to user iLIKE for case insensitivity. Then it worked better. I still like the answer below as it also helped to refine my syntax.
Hey i am also using this type of search logic in mine project, I had done in this way . If you want to try then look if it might helps you -:
class << self
def search(query)
product = "%#{query}%"
where("name LIKE ? AND locale =?", product,I18n.locale)
end
end
Thanks
I notice that you're using capitalize. Are you sure that the product name is being formatted in the exact same way that you're storing the data? Could it be that the code is returning "Card guides" but your data expects "Card Guides"?
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!
I have a Rails 3.0 web app that allow user to create own path to the application.
example : www.my_app.com/user_company_name
So I store a custom path in user DB field. User can changing path throught a input.
I have added this validation in model
validates_presence_of :custom_page
validates_format_of :custom_page, :with => /^([a-z]|[0-9]|\-|_)+$/, :message => "Only letter (small caps), number, underscore and - are authorized"
validates_length_of :custom_page, :minimum => 3
validates_uniqueness_of :custom_page, :case_sensitive => false
But I don't know how I can validate url to check it isn't in conflict with another route in my routing.
For example in my route.rb I have
resources :user
Validation need to don't allow using www.my_app.com/user, how I can do that?
Thanks, vincent
In your routes, you match the company name to a variable
match 'some_path/:company_name.format'
you can then do the lookup using company_name which rails will populate for you.
Validating the uniqueness of the custom_page variable should be enough to ensure there's no overlap. (note that validate uniqueness of doesn't scale -- if this will be big, you need a db constraint as well) as long as users can only specify one field.
If you're letting users specify
'some_path/:custom_path_1/:custom_path_2.format'
then you have to validate across both fields, and now it's getting messy. Hope you're not doing that.
You can try a custom validation to weed out "user"
validate :custom_page_cant_be_user
def custom_page_cant_be_user
errors.add(:custom_page, "can't be `user`") if self.custom_page =~ /^user$/i
end
assuming :custom_page comes in as a basic [a-z], if :custom_page has /user you need to update the regex a bit.