Ruby on Rails 3, Changing Views - ruby

Im working with Rails 3.0.9 and Ruby 1.9.2.
I have a search page that will display a list of results in grid format. However, I want to be able to give the user an option to display them in list format.
Could anyone please advise me about how I can offer a change view option,and still keep the search results?

As you have not specified where query is stored,
I will hope that in url, like example.com/search?query=mylookupstring
So in this case all we need is to place somewhere on a page, link_to search path and pass your query + some parameter back to controller to prepare new view
<%= link_to "List", search_some_thing_path(:query=>params[:query],:list=>true) %>
nice & easy
Post your details if i show bad skills with telepathy today.
UPDATE:
Pay attention to params & url. Yours & my example. You shouldn't just copy
as your controller expects params[:search] not params[:query]
So fix error in you link_to & move_on!
PS Great tip to find out how rails really work is to use debugger.
You may attach it in view
<% debugger %> or in model/controller simply debugger
Don't forget to include debug gems in your Gemfile, smth like
group :development, :test do
gem 'ruby-debug19'
end

Related

How to pass Ruby variable's value from a Ruby page to a Ruby template

Let's say I have a Ruby files structure like this:
app.rb
/views/index.erb
/views/layout.erb
app.rb is the main app file that contains the routes. Let's say I have one route as this:
get "/" do
erb :index
end
In layout.erb I have my html head and closing </body> and </html> and etc. It is also where I have <head>..</head> and where I can put that scope for some JavaScript methods.
Let's say now that I have my Ruby logic in index.erb. I get a value somehow from my logic (index.erb) and I want to pass that value to my layout.erb. Is it possible? If so, how we do that?
I have checked the #variable_name to pass it as argument from the route definition:
get "/" do
#variable_name = ??? -> this do not works since I did not get the logic yet from index.erb, no?
erb :index
end
I also have tried to use simply <%= variable_name %> or #{variable_name} directly in the layout.erb but without any success.
I actually found out that I was able to transport my "code" to view the widgets I wanted to populated in the index.erb so by that I resolve my problem of accessing the value that was define from a variable declared in index.erb.
Problem solved and a better way to work with Ruby as this issue makes me read more about how to structure myself (Thx to Dave).

How to render Mustache partials in Sinatra while using ERB as the primary tempate engine

I have a sinatra app that is mostly using erb for templates, but I am adding some mustache partials for blocks of html that need to be rendered on both the server and client side. I have a "views" directory where I'm keeping all my templates, including the mustache templates I'm adding. For example, the structure looks something like this:
views/
index.html.erb
_wingding.html.erb
_widget.html.mustache
Let's say I'm rendering index.html.erb using this endpoint:
get '/' do
erb :index
end
And inside that template, I want to render both of the above partials [UPDATE: it turns out this partial method is not built into sinatra, but is included via a gem (see my answer for details), but it still relies on the main sinatra rendering component, so the problem here still stands.]. So index.html.erb contains:
<%= partial :wingding %>
<%= partial :widget %>
The erb partial (wingding) renders fine, but the mustache partial (widget) does not. It causes the application to throw an exception:
Template engine not found: mustache
I have included the 'mustache' gem in the project. I tried 'require mustache/sinatra' and register Mustache::Sinatra. Both of these statements worked, but didn't solve the problem above. Any idea how to tell sinatra about mustache so that it can render mustache partials?
I'm setting my views directory by including this configuration:
configure do
set :views, File.join(File.dirname(__FILE__), 'views')
end
Version numbers:
sinatra 1.3.1
mustache 0.99.4
ruby 1.9.3
So it turns out the gem listed in the solution in my other answer caches output, meaning you can't use it to include the same partial with different locals in the same request, which makes it worthless for my purposes. So here's another (admittedly hackish) solution that I've settled on. I created a helper that will just deliver the contents of a given view:
helpers do
def template_contents(path)
File.open("#{settings.views}/#{path}") { |f| f.read }
end
end
Then, I just do a regular Mustache#render:
<%= Mustache.render(template_contents('_widget.html.mustache'), { ... }) %>
This works great for my use case.
I figured this out. First, I must note something I didn't realize when I posted the question. partial is not actually built into sinatra. It is being included in my app as part of the sinatra-more gem (discontinued, most of it's functionality is now in a project called padrino, but still using sinatra-more in this app). The partial method is included like this:
require 'sinatra_more/render_plugin'
module Sinatra
register SinatraMore::RenderPlugin
end
Anyway, that just adds the partial method (along with some other rendering helpers) but this method falls back on the built-in sinatra rendering code, so this fact is independent of the actual issue at hand in this question -- that sinatra does not by default recognize the mustache template engine. Turns out someone created a super simple gem to make it work, sinatra-mustache. You simply include the gem and require the library:
require 'sinatra/mustache'
That's it -- it just works! No additional configuration necessary. If you're curious how it works, the source code is pretty simple. It's by no means a one-liner to register a new template engine with sinatra (even saying "register" is a misnomer -- you basically have to implement it), but it's still fairly simple.
UPDATE: This gem caches the output for a given request/template, so you can't use it a second time with different locals. I could see cases where that's okay, but that makes it worthless for my use case.

link_to_unless_current method without Rails

I'm creating a site using a small Ruby framework, Sinatra, but I would like to be able to do something like what the Rails link_to_unless_current method does, without using Rails.
Now I have my own link_to method, which works the same as the Rails one, more or less, so how would I go about doing the _unless_current part?
Seeing as how you mentioned your link_to method is similar to the Rails one, give this a try:
def link_to_unless_current(text, location)
if request.path_info == location
text
else
link_to text, location
end
end
I gave this a quick test and worked perfectly for me, however if your link_to method takes more parameters, it's pretty simple to add more, just add them to the _unless_current(text, location, param1, param2, etc) and the link_to text, location, param1, param2, etc parts of the code.

Rails3 and automatic nofollow links

i have some model, let it be Post with field :content. Any user can submit post with html (with links of course:) ) and i'd like to set nofollow on those links. Is there any rails plugin to automate this task? Does this plugin have ability to manage "nofollowing" in conditional way - e.g. admin can add links without nofollow, but other - with only nofollow?
This should do what you're looking for: https://github.com/rgrove/sanitize/
Install the plugin, then for a block of text you can run:
<%=raw Sanitize.clean(#your_html, Sanitize::Config::BASIC) %>
There are other options that you can use to customise it, but the Config::BASIC version will detect all links in that block of text and add the nofollow tag to them.
You can define a helper for this, overriding (or rather wrapping) the default link_to
In app/helpers/posts_helper.rb do something along the lines of:
def nf_link_to(link_text, post)
opts = {}
opts[:rel] = "nofollow" unless post.author == "admin"
return link_to text, post, opts
end
So that in your view you can do:
<%= nf_link_to post.title, post %>
Which should result in:
My First[tm] Post
You should have a good look at the actual implementation of link_to and make your ''nf_link_to'' as complex as (as in; passing arguments and perhaps a block) as you desire.

Creating a plist in Rails 3

I'm new to Rails and I'm trying to learn it using Rails 3 (RC).
I have managed to use http://plist.rubyforge.org/ for supporting the output of plists. I would like to check with you guys to see if my approach is the right way to do it. Here goes:
In the gemfile I added gem 'plist'
In config/initializers/mime_types.rb I added Mime::Type.register "application/plist", :plist
In the controller, I added format.plist { render :plist => #product } in show
In the model, I added
def to_plist
attributes.to_plist
end
And finally, in the view file show.plist.erb, I have <%= raw #product.to_plist %>
Accessing for instance /products/2.plist works fine, but being new to Rails, I'm wondering if there are anything I should have done differently.
Looks right to me.
The only suggestion I have is to perhaps mix in the to_plist method into ActiveRecord::Base so that you don't have to define it over and over in each model. Perhaps this method will even support render_with syntax?
I'm about to do something similar myself.

Resources