Is it possible to add "search" function to the messaging gem "Mailboxer"? - ruby-on-rails-3

I'd like to implement "text search function" over body part of tons messages.
If anyone knows how to implement that to "Mailboxer", please show me how.
I have no idea how it goes.
When I access example.com/messages/search?page=3&search=test&utf8=%E2%9C%93
This code won't send back correct result...
def search
#search = params[:search]
#a = current_user.search_messages(#search)
#messages = Kaminari.paginate_array(#a).page(params[:page]).per(10)
render :received
end

This can be a good start:
https://github.com/frodefi/rails-messaging#enabling-search

Related

bullet proof way to find pages in Refinery Cms

i can find a page I'm looking for just fine, like this:
#my_page = ::Refinery::Page.find('foo')
so then i can say <% link_to #my_page.url %>
i then try and protect against the case where that page is deleted, like so:
if ::Refinery::Page.find('foo').present?
#my_page = ::Refinery::Page.find('foo')
else
#my_page = nil
end
i've actually tries several ways of doing this, with exists?, with nil?, etc. the above is the most basic.
So I then go and delete my page and I get a record not found error.
Couldn't find Refinery::Page with id=foo
Shouldn't the present? method protect against that error? How should I be doing that?
When you do
#my_page = ::Refinery::Page.find('foo')
it tries to find page by slug first and if it doesn't find it then it tries to find it by id.
If you don't deal with localization you can do
#my_page = ::Refinery::Page.find_by_slug('foo')
which will return page if it finds it or nil if it doesn't.
With localization it get's complicated but this should do the trick
if ::Refinery::Page::Translation.find_by_slug('foo').present?
#my_page = ::Refinery::Page::Translation.find_by_slug('foo').refinery_page
end
How about following the principles of EAFP?
begin
#my_page = Refinery::Page.find('foo')
rescue ActiveRecord::RecordNotFound
#my_page = nil
end

rails user input with <script>, stored, and displayed

I have an application that collect user input and store to DB and show back to user.
One user entered "alert(1)" into the name field and saved it into DB.
Whenever the name is displayed, the page will be broken.
I know how to fix that input only with validation for input, and h() for output.
However, I have so many input fields and so many outputs that accept users' text.
Is there any simple way to prevent this happening(i.e. overriding params method, etc)?
I also want to know how you expert guys are dealing with this problem?
As of Rails 3, my understanding was that embedded ruby code was html escaped by default. You don't need to use h() to make it that way. That is, if you use <%= "<script>a=1/0;</script>" %> in a view, the string is going to be made html safe, and so the script doesn't execute. You would have to specifically use raw() or something similar to avoid it - which you should naturally not do unless you're really confident about the contents.
For output, Rails 3 automatically html-encode all text unless I use raw() method.
For input, How about making a common validator and apply to all fields that are text or string? Is it desirable?
http://api.rubyonrails.org/classes/ActiveModel/Validator.html
class MyValidator < ActiveModel::Validator
def validate(record)
record.class.columns.each do |c|
if c.type==:text || c.type == :string
record.errors.add c.type, "script tag is not allowed" if c[/<script[^>]*>/]
end
end
end
end

What's a good way to insert a resource id into the params of another resource?

I'm really new to programming, so I'm having trouble explaining this -- please forgive.
I have a Document model and a Note model in my rails app. A note belongs to a document, and a document has many notes -- the foreign key in the notes table is document_id.
On my document show page, I have a form for a note which uses a :content attribute as a text_area field.
What I'd like to do is pass the document's id into the note params so the note would have both the :content the user submits alng with the :document_id based on the document_path.
Currently I'm adding the :document_id into the note's params hash using a hidden_field form helper, and sending the whole thing to the NotesController, but I hope there's a cleaner / perhaps easier way.
If this makes sense, can someone suggest a better way to do this? Thank you.
In your routes have something like
resources :documents do
resources :notes
end
Then you should be adding a note via this route
/documents/5/notes/new
Then in your NotesController have
def create
#document = Document.find(params[:document_id])
#note = #document.notes.build(params[:note])
if #note.save
# Blah
else
# Blah
end
end
(In no way has this been tested - but it gives you an idea of how to do it in a RESTFUL style without hidden fields)

Displaying Error Message with Sinatra

I'm writing a simple app that takes standard input from the user. As for the email entry, I have it verify if it is in a standard email format and then have it list the problems like this when a new instance is going to be saved:
u = User.new
u.email = params[:email]
u.save
if u.save
redirect '/'
else
u.errors.each do |e|
puts e
end
end
I know that if it is correct it should return back to the home page. If it is wrong I want it to return to the home page as well, but I want it to return an error value (so I can have a pop-up or just something onscreen letting the user know that the format of the email was wrong). What would be the best way to do this?
You can use the 'sinatra-flash' gem to display all kinds of errors/notices etc.
u = User.new
u.email = params[:email]
u.save
if u.save
redirect '/'
else
flash[:error] = "Format of the email was wrong."
redirect '/'
end
Then you need to say where you want the flash[:error] to be displayed. Normally I put this in the layout.haml or (erb) file right above where I yield in the content.
layout.haml:
- if flash[:error]
%p
= flash[:error]
Also, make sure you include the gem and enable sessions
require 'sinatra'
require 'sinatra/flash'
enable :sessions
You could also try the 'rack-flash' gem. There is a tutorial for using it at http://ididitmyway.heroku.com/past/2011/3/15/rack_flash_/
You can save a potentially costly trip back and forth by doing it in Javascript. The way I see it, simple validation like this is a client function, handled by some code attached to an onBlur event, not something I need to verify on my side (except for sanitization, obviously).
To directly answer your question, I've used regular instance variables to store an "error array" in #errors. Form-specific errors, or errors that need to be displayed in a certain place on the page, rather than at the top, get stored in #form_errors or something similar. Then the template checks to see if there are errors and renders them accordingly.

Complete noob Jquery / Rails setup question (probably)

Background: I've been doing RoR for about a year now, and am fairly comfortable with it, however, I know next to nothing about Javascript.
I've been playing around with some jquery autocomplete stuff in my rails app. I pretty much had a version working, but needed some tokenized fields too for a one to many relationship.
Right on cue - good old Ryan Bates does a railscast on it. So I start following the instructions.
Got a little bit nervous when I had to start installing 'jquery-rails' gem (I'd already installed jrails to get the other stuff working).
As suspected, it broke some stuff but I managed to get that working again.
Anyway, I got most of the way through the tutorial, and everything was going fine - I've got the tokenizer script to find the correct input field and it acts as expected. I've tested the json link too - that sends back all the right stuff.
However when I start typing in the text field - nothing happens, and when I view the console window it comes back with:
Uncaught TypeError: Cannot call method 'replace' of undefined
jQuery.jQuery.extend._Deferred.deferred.resolveWith
done
jQuery.ajaxTransport.send.callback
I can make guesses as to why this is going wrong - but any expert advice would be greatly appreciated.
(I should also add - I'm using formtastic too)
Thanks in advance.
Ok, finally figured it out.
It turns out that my author's name column is not name but rather author. So I needed to make a change inside the js.coffee script to override that default search of name.
The line you need to use is:
propertyToSearch: "author"
My whole book.js.coffee file now looks like this:
jQuery ->
$('#book_author_tokens').tokenInput '/authors.json'
theme: 'mac'
prePopulate: $('#book_author_tokens').data('load')
propertyToSearch: "author"
This actually fixed the error Uncaught TypeError: Cannot call method 'replace' of undefined
Of course, if you do use a different column name you will want to also edit the functions in the author.rb file to reflect that:
def self.tokens(query)
authors = where("author like ?", "%#{query}%")
if authors.empty?
[{id: "<<<#{query}>>>", author: "New: \"#{query}\""}]
else
authors
end
end
def self.ids_from_tokens(tokens)
tokens.gsub!(/<<<(.+?)>>>/) { create!(author: $1).id }
tokens.split(',')
end
Edit
Another thing I had to do for the fieldsto be prepopulated with the existing authors was change this:
= f.input :author_tokens, :data => { :load => #book.author }
To this:
= f.input :author_tokens, :input_html => { :data => { :load => #book.author } }
And then they would show up.
Hope this helps you.