Randomizing Rails Root Path between two views? - ruby-on-rails-3

Is there a way I can switch between to views at random for the root path?
root :to => 'pages#blue' or root :to => 'pages#red'
Thanks for any kind of help with this.

You can pass a lambda as the value of :to, so theoretically you could return two different responses randomly. It might be a better idea to swap the layout/view that's rendered though.
Edit
root to: lambda {|env| [ 302, {'Location'=> your_randomizing_code_here }, [] ]}
You could do that, or something very similar in your controller:
class YourRootController < ActionController::Base
def index
render some_method_that_returns_your_view_paths_randomly
end
end

Related

Rails 3 how to render .json.erb file

I'm working on migrating a rather big project to Rails 3.
Here's my controller action:
def recent
#account = Account.find(session[:account_id])
render :layout => false
end
Here's my recent.json.erb file
formatted_account =
{
:code = 1,
:id = #account.id,
:prefix = 2
}
formatted_account.to_json()
I'm using jQuery.getJSON to get this data, when I get the response, this is what I get:
[{"code":1,"id":"1 "prefix":2}]
Instead of
[{code:1, id:1, prefix:2}]
I had to use safe_html in some other pieces of code to solve escaping issues like this but in this case I can't figure out how to solve without getting rid of the .json.rb file and rendering a json object in a proper way.
html_safe did the trick:
formatted_account =
{
:code = 1,
:id = #account.id,
:prefix = 2
}
formatted_account.to_json.html_safe
If you want to build up json from a template you'll need to use some kind of builder as ERB won't really cut it.
JBuilder comes commented out in a fresh Rails 3.2 Gemfile. Haven't used it myself but it seems well thought out with a clean DSL. There's also a list of links at the bottom of the README on the JBuilder github page.
RABL is another tool for building JSON, as well as supporting multiple other formats.
JBuilder
RABL

Override html in active_admin gem

I wanna override html code when working with active_admin gem in Rails; because the nav-bar and many elements in these gem's views are different with my views (other pages). I hope that has a way to change html code without changing css manually! Thanks
It is not very easy , activeadmin use DSL for building html (called "Arbre")
You have to monkey patch every page class, also , it may prevent customizing of css too.
For example to move sidebar to left, create initializer with next patch.
class ActiveAdmin::Views::Pages::Base < Arbre::HTML::Document
def build_page_content
build_flash_messages
div :id => "active_admin_content", :class => (skip_sidebar? ? "without_sidebar" : "with_sidebar") do
build_sidebar unless skip_sidebar?
build_main_content_wrapper
end
end
end
default method was
def build_page_content
build_flash_messages
div :id => "active_admin_content", :class => (skip_sidebar? ? "without_sidebar" : "with_sidebar") do
build_main_content_wrapper
build_sidebar unless skip_sidebar?
end
end
The full list of classes used for rendering can be found here , so some of them you need to patch.
https://github.com/gregbell/active_admin/tree/master/lib/active_admin/views
Be ready for a big piece of work.
UPD. Gem for changing activeadmin sidebar position
https://github.com/Fivell/active_admin_sidebar

Rails 3: mixing "generic" controller routes with standard resource routes

I've got a set of routes that looks like this:
resources :placements do
match '/foo' => "placements#foo"
match '/bar' => "placements#bar"
end
This produces routes that behave like you would expect:
/placements/1234/foo
/placements/1234/bar
However, I also need "generic" routes for a few methods that do not need an individual placement. So, I build a routes block that looks like this:
resources :placements do
match '/foo' => "placements#foo"
match '/bar' => "placements#bar"
end
match '/placements/baz' => "placements#baz"
If I rake routes, I get a route that looks good:
/placements/baz
Note the lack of an id. However, if I try to visit that route, Rails tries to call the show method on the controller instead, as if "baz" was an ID, instead of a method name. How can I build a routing structure that gives me what I am after, without having to change the first segment of my route (placements), to something else?
Move the second route over the resources block ie,
match '/placements/baz' => "placements#baz"
resources :placements, :id => /\d+/ do
match '/foo' => "placements#foo"
match '/bar' => "placements#bar"
end
or add a regex for the id in resources, ie something like:
resources :placements, :id => /\d+/ do
match '/foo' => "placements#foo"
match '/bar' => "placements#bar"
end
match '/placements/baz' => "placements#baz"

Rails prevent layout during AJAX request

I have searched around and have not been able to find a solution for this type of mechanic. I want to load all pages normally in Rails, but whenever I do an ajax request I just want to return the page without the layout. So anytime I make an ajax requst I can append a ?page=true or something along those lines and have Rails just return the page without the layout.
Is this possible? Is there a better way to do it that I am missing?
Thanks for any help!
Final Solution Working Code:
In the controller all you need to do is append a little logic to the format.html in the respond_to block.
In the show method for example
def show
# code beforehand
respond_to do |format|
format.html { render :layout => !request.xhr? }
# other formats
end
end
And that's it! Prevent layouts during AJAX requests!
Note: Thanks to the smathy's comment on his answer this was simplified further. I originally had format.html { render :layout => nil if request.xhr? } This solution works just as well, but smathy's modification keeps it even simpler.
You don't need to add that parameter, request.xhr? will return true in your controller when it's an Ajax request. Just use that to decide whether to render the layout or not.

How do you have a default Gravatar that is external and that actually resizes properly?

To implement Gravatar in my Rails3 application, I'm using the gravatar_image_tag gem in a helper, but I'm having issues when mixing 2 config options:
If the user doesn't have a gravatar attached to his email a default image is rendered; but I want it to reference an external file (e.g., http://www.iconfinder.com/ajax/download/png/?id=43350&s=128 instead of :identicon or others)
I also want the image to be resized on the fly to, let's say 50px.
Independently, both options work as expected, but when I put them together:
def gravatar_for(user, options = { :default => 'http://www.iconfinder.com/ajax/download/png/?id=43350&s=128', :size => 50 })
gravatar_image_tag(user.email.downcase, :alt => user.full_name,
:class => 'gravatar',
:gravatar => options)
end
the size option is not applied, and the gravatar gets rendered in it's full size (128px in this case).
What am I doing wrong, or how can I achieve this combination?
Gravatar will not resize your default image for you. I assume that it just 302s to the ulr gave as a default if it does not find an gravatar for the email you gave it. It looks like the 's' parameter in the iconfinder url is for the size you are trying to grab but that icon does not have a size of 50px available only 128, 256, and 512
Example:
http://www.iconfinder.com/ajax/download/png/?id=43350&s=256
If you wanted a 50px and 80px versions of the icon I would save it to your applications public/image directory as default_gravatar_50.png and default_gravatar_80.png respectively and change your method like so.
end
def gravatar_for(user, options = {})
options = { :size => 50 }.merge(options)
options[:default] = image_tag("default_gravatar_#{options[:size]}.png
gravatar_image_tag(user.email.downcase,
:alt => user.full_name,
:class => 'gravatar',
:gravatar => options)
end
Or if you find an icon on icon finder that is the size(s) you like change the setting of the default option like so.
options[:default] = "http://www.iconfinder.com/ajax/download/png/?id=43350&s=#{options[:size]}"
Iconfinder here. You don't want to link to the download script. Instead just grab the URL to the image it self so you wan't get a lot of header information.