bullet proof way to find pages in Refinery Cms - ruby-on-rails-3

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

Related

Rails routing to external site from model column through controller

I'm having an issue in my controller. I'm making url objects with original_url short_url and sanitized_url. I can create and save the links just fine. The issue i'm having is when following the short link back to mysite.com/short_url it needs to go through the controller show and grab the sanitized url and redirect to that external site.
Can someone help me figure out what's wrong with this code?
I'm getting undefined method 'sanitized_url'
urls_controller.rb - show
short = params[:short_url]
#url = Url.where("short_url = ? ", short)
redirect_to #url.sanitized_url
My routes.
root to: 'urls#index'
get "/:short_url", to: "urls#show"
get "shortened/:short_url", to: "urls#shortened", as: :shortened
resources :urls
Thank you
undefined method 'sanitized_url'
where returns AR collection. You need to apply sanitized_url on an instance
Below should work
short = params[:short_url]
#url = Url.where("short_url = ? ", short).first
redirect_to #url.sanitized_url

How do I do a redirection in routes.rb passing on the query string

I had a functioning redirect in my routes.rb like so;
match "/invoices" => redirect("/dashboard")
I now want to add a query string to this so that, e.g.,
/invoices?show=overdue
will be redirected to
/dashboard?show=overdue
I've tried several things. The closest I have got is;
match "/invoices?:string" => redirect("/dashboard?%{string}")
which gives me the correct output but with the original URL still displayed in the browser.
I'm sure I'm missing something pretty simple, but I can't see what.
You can use request object in this case:
match "/invoices" => redirect{ |p, request| "/dashboard?#{request.query_string}" }
The simplest way to do this (at least in Rails 4) is do use the options mode for the redirect call..
get '/invoices' => redirect(path: '/dashboard')
This will ONLY change the path component and leave the query parameters alone.
While the accepted answer works perfectly, it is not quite suitable for keeping things DRY — there is a lot of duplicate code once you need to redirect more than one route.
In this case, a custom redirector is an elegant approach:
class QueryRedirector
def call(params, request)
uri = URI.parse(request.original_url)
if uri.query
"#{#destination}?#{uri.query}"
else
#destination
end
end
def initialize(destination)
#destination = destination
end
end
Now you can provide the redirect method with a new instance of this class:
get "/invoices", to: redirect(QueryRedirector.new("/dashboard"))
I have a written an article with a more detailed explanation.

Make URL be title of post

Currently my URL's appear as www.website.com/entries/1, I'd like to make them appear as www.website.com/title-of-entry. I've been messing around with routes and have been able to get the entry title to display in the URL, but Rails is unable to find the entry without supplying an ID. If I send the ID along with the parameters, the URL appears as www.website.com/title-of-entry?=1. Is there anyway I can pass the ID without having it appear in the URL as a parameter? Thanks!
Like most things, there's a gem for this.
FriendlyID.
Installation is easy and you'll be up and running in minutes. Give it a whirl.
Ususally you'll want to to save this part in the database title-of-entry (call the field slug or something`). Your model could look something like this:
class Entry < ActiveRecord::Base
before_validation :set_slug
def set_slug
self.slug = self.title.parameterize
end
def to_param
self.slug
end
end
Now your generated routes look like this: /entries/title-of-entry
To find the corresponding entries you'll have to change your controller:
# instad of this
#entry = Entry.find(params[:id]
# use this
#entry = Entry.find_by_slug(params[:id])
Update
A few things to bear in mind:
You'll have to make sure that slug is unique, otherwise Entry.find_by_slug(params[:id]) will always return the first entry with this slug it encounters.
Entry.find_by_slug(params[:id]) will not raise a ActiveRecord::RecordNotFound exception, but instead just return nil. Consider using Entry.find_by_slug!(params[:id]).
If you really want your routes to look like this /title-of-entry, you'll probably run into problems later on. The router might get you unexpected results if a entry slug looks the same as another controller's name.

Is it possible to add "search" function to the messaging gem "Mailboxer"?

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

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.