Passing parameters to erb view - ruby

I'm trying to pass parameters to an erb view using Ruby and Sinatra.
For example, I can do:
get '/hello/:name' do
"Hello #{params[:name]}!"
end
How do I pass :name to the view?
get '/hello/:name' do
erb :hello
end
And how do I read the parameters inside view/hello.erb?
Thanks!

just pass the :locals to the erb() in your routes:
get '/hello/:name' do
erb :hello, :locals => {:name => params[:name]}
end
and then just use it in the views/hello.erb:
Hello <%= name %>
(tested on sinatra 1.2.6)

Not sure if this is the best way, but it worked:
get '/hello/:name' do
#name = params[:name]
erb :hello
end
Then, I can access :name in hello.erb using the variable #name

get '/hello/:name' do
"Hello #{params[:name]}!"
end
You cannot do this in routes.
You want to set the params in the controller.
app/controllers/some_controller.rb
def index
params[:name] = "Codeglot"
params[:name] = "iPhone"
params[:name] = "Mac Book"
end
app/views/index.html.erb
<%= params[:name] %>
<%= params[:phone] %>
<%= params[:computer] %>

Related

Proc inside ERB

There's something weird going on here that I can not understand when I try to implement multiple content_for blocks in ERB using plain Ruby.
Here is my code:
# helper.rb
require 'erb'
def render(path)
ERB.new(File.read(path)).result(binding)
end
def content_for(key, &block)
content_blocks[key.to_sym] = block
end
def yield_content(key)
content_blocks[key.to_sym].call
end
def content_blocks
#content_blocks ||= Hash.new
end
And template:
<% #test.html.erb %>
<% content_for :style do %>
style
<% end %>
<% content_for :body do %>
body
<% end %>
<% content_for :script do %>
script
<% end %>
When I open irb to test, I get
irb(main):001:0> require './helper'
=> true
irb(main):002:0> render 'test.html.erb'
=> "\n\n\n"
irb(main):003:0> content_blocks
=> {:style=>#<Proc:0x005645a6de2b18#(erb):2>, :body=>#<Proc:0x005645a6de2aa0#(erb):5>, :script=>#<Proc:0x005645a6de2a28#(erb):8>}
irb(main):004:0> yield_content :script
=> "\n\n\n\n script\n"
irb(main):005:0> yield_content :style
=> "\n\n\n\n script\n\n style\n"
Why yield_content :script got the \n\n\n prepended and why yield_content :style got the script\n\n in result.
If you do
ERB.new(File.read(path)).src
Then you can see what erb compiles your template to. The template ends up looking like (formatted for readability)
_erbout = ''
_erbout.concat "\n"
#test.html.erb
_erbout.concat "\n"
content_for :style do
_erbout.concat "\n style\n"
end
Where _erbout is the buffer that accumulates the output from your template. _erbout is just a local variable,m
When you call your procs they are all just appending to that same buffer, which already contains the result from the template render.

Rack::Session::Pool Sessions in Sinatra

I can't seem to get these sessions to continue into other pages.
app.rb:
class MyApp < Sinatra::Base
use Rack::Session::Pool, :expire_after => 60 * 1
get "/" do
#foo = "one two three"
erb :index
end
get "/first" do
session[:foo] = Time.now
session[:message] = "ALPHA"
session[:message1] = "CHARLIE"
erb :first
end
get "/second" do
session[:message2] = "BRAVO2"
erb :second
end
end
Inside /first and /second:
Sess: <%= session.inspect %><br>
The session doesn't want to carry across pages. On /first I'm displaying this:
Sess: {"message"=>"ALPHA", "message1"=>"CHARLIE", "foo"=>2015-12-01 17:05:31 -0500}
On /second I'm displaying this:
Sess: {"message2"=>"BRAVO2"}
Just needed a restart. Figure that.

Ruby: How to pass a variable from server to index?

something = "0"
get "/" do
erb :index, :locals => something
end
When I do this and go to localhost, it says undefined method `keys' for "0":String. I am using sinatra. How do I pass a variable from server to index?
You're half way there, you just need to make something an object.
get "/" do
erb :index, :locals => {:something => 0}
end
and then just use it in the your index:
Something: <%= something %>

Rails 4 search bar

I'm trying to create a search bar in my Rails 4 app. I'm my user db has 'name' and 'email' columns for the user's - I want users to be able to search for other users by name or id.
I'm currently getting this:
ActiveRecord::RecordNotFound in UsersController#index
Couldn't find all Users with 'id': (all, {:conditions=>["name LIKE ?", "%hi#example.com%"]}) (found 0 results, but was looking for 2)
Does anyone know what I'm doing wrong? I've looked at railscasts and a few forums etc but cant get past this point at the moment.
index.html.erb:
<% form_tag users_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
model/user.rb:
def self.search(search)
if search
find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
else
find(:all)
end
end
users_controller.rb:
def index
#users = User.search(params[:search])
end
routes.rb:
get 'search' => 'users#index'
Are you using Rails 4? find(:all, ...) is the old way of doing things. find only takes ids now. Use:
def self.search(search)
if search.present?
where('name LIKE ?', "%#{search}%")
else
where(true)
end
end
Also present? will test against both nil and blank. Keep in mind that LIKE can be really slow depending on your database.
Searching in rails
By default rails doesn't support full text searching .Activerecord finder always find a record using the primary key ie. id.
Hence , we need some other gems or applications like sunspot, elasticsearch etc..
i'll show you using Sunspot solr here ..
in the gem file of your application just add the following code...
.
gem 'sunspot_rails'
group :development do
gem 'sunspot_solr'
end
and in terminal use
bundle install
rails g sunspot_rails:install
this will add solr and creates config/sunspot.yml file
rake sunspot:solr:start
rake sunspot:reindex
edit the user.rb lile in models
app/model/user.rb
Class User < ActiveRecord::Base
searchable do
text :name, :email
end
end
in app/controller/users_controller.rb
and then add in index function
def index
#search = User.search do
fulltext params[:search]
end
#users = search.results
end
Make a form to take a user input
<%= label_tag(:search, "Search for:") %>
<%= text_field_tag(:search) %>
<%= submit_tag("Search") %>
<% end %>

Blocks in pure ERB / Erubis

I have the following Ruby script:
require 'erubis'
def listing(title, attributes={})
"output" + yield + "more output"
end
example = %Q{<% listing "db/migrate/[date]_create_purchases.rb", :id => "ch01_292" do %>
<![CDATA[class CreatePurchases < ActiveRecord::Migration
def change
create_table :purchases do |t|
t.string :name
t.float :cost
t.timestamps
end
end
end]]>
<% end %>}
chapter = Erubis::Eruby.new(example)
p chapter.result(binding)
I am attempting to use a block here and get it to output "output", then the content in the block and then "more output", but I can't seem to get it to work.
I know that ERB used to work this way in Rails 2.3 and now works with <%= in Rails 3... but I'm not using Rails at all. This is just pure ERB.
How can I get it to output all the content?
Jeremy McAnally linked me to this perfect description of how to do it.
Basically, you need to tell ERB to store the output buffer in a variable.
The script ends up looking like this:
require 'erb'
def listing(title, attributes={})
concat %Q{
<example id='#{attributes[:id]}'>
<programlisting>
<title>#{title}</title>}
yield
concat %Q{
</programlisting>
</example>
}
end
def concat(string)
#output.concat(string)
end
example = %Q{<% listing "db/migrate/[date]_create_purchases.rb", :id => "ch01_292" do %>
<![CDATA[class CreatePurchases < ActiveRecord::Migration
def change
create_table :purchases do |t|
t.string :name
t.float :cost
t.timestamps
end
end
end]]>
<% end %>}
chapter = ERB.new(example, nil, nil, "#output")
p chapter.result(binding)
Great. I remember seeing that a while ago. Playing a bit I was getting this:
require 'erubis'
def listing(title, attributes={})
%Q{<%= "output #{yield} more output" %>}
end
example = listing "some title", :id => 50 do
def say_something
"success?"
end
say_something
end
c = Erubis::Eruby.new(example)
p c.evaluate
# => "output success? more output"

Resources