Ruby rails not creating instance variables - ruby-on-rails

I am using a lynda.com tutorial for Ruby on Rails. The very first instance of creating and using array instance variables does not work. At first I thought it was that #array might have become a reserve word in the newer 5.0 version of rails that I am using, but changing it did not cause the "nil" (undefined) error to go away.
What is wrong with Ruby Rails 5.0? It is refusing to define instance variables and to pass them to the appropriate template.
This is extremely aggravating, since rails is not behaving as documented (i.e. RAILS IS BRAIN DEAD OUT OF THE BOX).
****************
demo_controller.rb
class DemoController < ApplicationController
def index
render('hello')
end
def hello
#zarray = [1,2,3,4,5] <------------ this is defined
end
def other_hello
render(:text => "Hello EVERYONE!")
end
end
******************
hello.html.erb
<h1>Demo#hello</h1>
<p>Hello World!</p>
<%= 1 + 1 %> <------ works
<% target = "world" %>
</br>
<%= "Hello #{target}" %> <----- works
</br>
<% #zarray.each do |n| %> <---- line 10. Rails claims that #zarray is
not defined
<%= n %></br>
<% end %>
ActionView::Template::Error (undefined method `each' for nil:NilClass):

I copied and ran your code and it worked fine. I guess it could be down to the fact that controllers should as a rails convention be pluralized, and your controller is called DemoController and perhaps you've called demoS#action somewhere? So, generate a new controller from your terminal called:
DemosController
with the generator:
rails g controller Demos
And copy paste everything from the old controller to the new controller.
And in your routes.rb you need to first make sure you have the correct resources :demos (the name of your model) which will give you the standard RESTful resources (index, new, create, etc), but as your 'hello' method is not a part of the RESTful api, you need to create a custom route for that:
get 'hello' => 'demos#hello', :as => :hello
get = HTTP method
'hello' = The URL you want to hello.html.erb to be reachable on: localhost:3000/hello
'demos#hello' = demos is the DemosController and #hello is the action in the controller.
':as => :hello' (_path)is the named helper you can call in a link_to on any page for instance: link_to hello_path.

I am new to Ruby and Rails. I tested using a plain STRING instance variable, and THAT got passed from my controller to my template, so the issue was the array definition. Apparently the older form of array definition that was in the tutorial that I was using no longer works in the version of rails and ruby that I am using.
I am using Ruby on Rails 5.0.1 with Ruby 2.2.4p230 (2015-12-16 revision 53155) [i386-mingw32] on Windows (rails/ruby compatibility is kosher).
#zarray = [1,2,3,4,5] <-- the array is not defined when passed to template
#zarray = Array.new << 1 << 2 << 3 << 4 << 5 <-- this works
It is a bit distressing that Ruby does not even BOTHER to complain about the format of the array definition. It just DOES NOTHING (i.e., refuses to initialize the array).
In the template:
<% #zarray.each do |n| %>
<%= n %></br>
<% end %>
I should add that #zarray = {1,2,3,4,5] works if you use it after #zarray = Array.new
In other words, at some point in the evolution of Ruby, EXPLICITLY classing arrays was introduced? It is not always clear in the documentation. The earlier tutorial I was using does NOT explicitly class the array.
The problem seems to be in the current RAILS version (5.0.1) that I am running. I has done SOMETHING to destroy the ability of Ruby to create an array using array literal syntax. When I run array definitions with literal syntax in IRB, I have no problem creating them. So Ruby is fine. It is a serious BUG in the 5.0.1 version of rails. So I think I should report it.
Welcome to Git (version 1.8.1.2-preview20130201)
$ irb
irb(main):002:0> service_mileage = [5000,15000,30000,60000,100000]
=> [5000, 15000, 30000, 60000, 100000]
irb(main):003:0> service_mileage[0]
=> 5000
irb(main):004:0> service_mileage[2]
=> 30000
irb(main):005:0>

Related

Rails 5: Interpolated Single Quote Rendered As Unicode

Ruby version: 2.3.1
Rails version: 5.0.5
I am using Google's dataLayer to record ecommerce events in my site. We are in the middle of an upgrade from rails 4 to 5 and I'm running into a wall with one of my rails helpers. I use a helper to generate a product_list and inject it into the view so I can send it to the dataLayer.
In rails 4 the dom reflects what I write in the helper, including the quotes I need to include for the format. In rails 5 however, the quotes are being converted to unicode and I can't figure out why or how to avoid this. This is not happening when I bind on the method in the terminal, it's only happening when it is loaded in the dom. I've tried adding sanitize(), .html_safe, converting this to a hash and converting this to JSON and nothing is working.
Right now it is working on rails 4 like this:
def foo
result += "'var1':'#{item.id}',
'var2':'#{item.title}',
'var3':#{item.price}},{"
result
end
end
What I get in the DOM:
'products': [{
'var1':'result1',
'var2':'result2',
'var3': 'result3'
}]
What is being returned on the DOM in rails 5:
'products': [{
'var1':'result1',
'var2':'result2',
'var3': 'result3'
}]
Not sure where you called html_safe, I quickly added this to a view I had in Rails 5 to attempt to replicate and here are my results:
View Helper
module HomeHelper
def result
"{'var1':'test'}".html_safe
end
end
View
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
<%= result %>
Generated Page
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
{'var1':'test'}

How to replace erb with liquid?

I'd like to use liquid in my Rails app. I've installed the gem. In order to use in all templates, I've created a library (lib/liquid_view.rb:):
class LiquidView
def self.call(template)
"LiquidView.new(self).render(#{template.source.inspect}, local_assigns)"
end
def initialize(view)
#view = view
end
def render(template, local_assigns = {})
#view.controller.headers["Content-Type"] ||= 'text/html; charset=utf-8'
assigns = #view.assigns
if #view.content_for?(:layout)
assigns["content_for_layout"] = #view.content_for(:layout)
end
assigns.merge!(local_assigns.stringify_keys)
controller = #view.controller
filters = if controller.respond_to?(:liquid_filters, true)
controller.send(:liquid_filters)
elsif controller.respond_to?(:master_helper_module)
[controller.master_helper_module]
else
[controller._helpers]
end
liquid = Liquid::Template.parse(template)
liquid.render(assigns, :filters => filters, :registers => {:action_view => #view, :controller => #view.controller})
end
def compilable?
false
end
end
And added the following initialiser (config/initializers/liquid_template_handler.rb:):
require 'liquid_view'
ActionView::Template.register_template_handler :liquid, LiquidView
PS: I've followed these instructions.
Now, if rename a template file with liquid my_template.html.liquid the <%= stylesheet_link_tag 'mycss' %> stopped working, but more importantly the {{user.first_name}} variable did not print. In my controller I have #user = current_user
What am I missing?
My intention is to completely override erb with liquid in some templates, so ideally it should work like erb (in a sense that I can pass variables from the controller and simply render it in the template without using Liquid::Template.parse(#page.template) which by the way, I don't understand how it works on a file-based template.
PS: I'm also using [this] gem (https://github.com/yoolk/themes_on_rails) for separate templates. I'm not sure it does any impact on it.
PPS: I've seen this but doesn't apply as its a older version of Rails and I'm not using prepend.
PPPS: I'm using Ruby 2.2.2 and Rails 4.2
I hope this not the problem you are thinking it is . You can check the way as it was said here Github Description
Did you create a Drop to access #user?
https://github.com/Shopify/liquid/wiki/Introduction-to-Drops
Liquid is a safe template system, so we can interpret on the backend templates that are created by the user. To access anything non trivial (number, string, hashes or arrays) you need a Drop, which is a controlled interface to define what the templates can access.
This is by design and for security reasons.

Redmine-PlugIn development: helper method not found in view

I'm writing a plugin for redmine and there is one thing i just don't get:
I have a helpermodule called approvals_helper.rb which contains a method 'rev_approved?'
module ApprovalsHelper
def rev_approved?(repository, revision)
# return some boolean value
end
end
Now i want to use this method in my view which is a partial and is called _approved.html.erb
<% if rev_approved?(#repository, #revision) %>
<p>show something</p>
<% end %>
This partial is rendered in the revision.html.erb (from redmine view/repositories)
But when i do i get this error message:
ActionView::Template::Error (undefined method `rev_approved?' for #<#<Class:0x7f801e6bf030>:0x7f801e669ae0>)
When i add "include ApprovalsHelper" directly to the ApplicationHelper it all works fine, but i don't want to change the code directly. Is there a way to do this in a my plugin?
Is this because i actually render my partial in the revision view? How can I get this to work?
I'm using redmine 2.3.1 , ruby 1.8.7 and rails 3.2.13
Many thanks!
in your init.rb add
require_dependency 'name_of_helper'

Accessing plain old ruby object in Spree 1.1

I have a Spree 1.1 project that's in my rails 3.2 app with a plain ruby object in app/models/MyObject.rb
class MyObject
def self.some_method
# do stuff
end
end
I'm trying to access the model in an override partial
Deface::Override.new(:virtual_path => 'spree/products/show',
:name => 'unique_name',
:insert_after => "[data-hook='product_description']",
:partial => 'shared/product_show_stuff')
And here's my partial
<%= MyObject.some_method %>
The error I get is
uninitialized constant ActionView::CompiledTemplates::MyObject
So I tried the following, hoping the object would be accessible via the global namespace
<%= ::MyObject.some_method %>
Then I get this error:
uninitialized constant MyObject
How can I access my newly created ruby object?
Your constant should be defined inside a file with a lowercase name:
app/models/my_object.rb
Not:
app/models/MyObject.rb
This is so that Rails's autoloading works sufficiently.

Has namedspaced routing changed in Rails 2.3?

I have an admin namespace which gives me the usual routes such as admin_projects and admin_project, however they are not behaving in the usual way. This is my first Rails 2.3 project so maybe related I can't find any info via Google however.
map.namespace(:admin) do |admin|
admin.resources :projects
end
The strange thing is for a given URL (eg. /admin/projects/1) I don't have to pass in an object to get URL's it somehow guesses them:
<%= admin_project_path %> # => /admin/projects/1
No worries, not really a problem just not noticed this before.
But if I try and pass an object as is usual:
<%= admin_project_path(#project) %> # => admin_project_url failed to generate from {:controller=>"admin/projects", :action=>"show", :id=>#<Project id: 1, name: "teamc...>
":id" seems to contain the entire object, so I try passing the id directly and it works:
<%= admin_project_path(#project.id) %> # => /admin/projects/1
This would not be so bad but when it comes to forms I usually use [:admin, #object], however:
<%= url_for [:admin, #project.id] %> # => undefined method `admin_fixnum_path'
So I can't pass in an id, as it needs an objects class to work out the correct route to use.
<%= url_for [:admin, #project] %> # => Unfortunately this yields the same error as passing a object to admin_project_path, which is what it is calling.
I can't spot any mistakes and this is pretty standard so I'm not sure what is going wrong...
Interesting. What happens when you define a to_param method on Project? For instance
class Project < ActiveRecord::Base
def to_param
self.id
end
end
This should be the default and this shouldnt be necessary. But what happens if you make it explicit? Try adding the above method then going back to your original approach of only passing around #project
I wish I could help you on this one. We have a large application with several namespaced sections. Our routes are defined in the exact method you have described and we are calling our path helper with objects. No where in the application are we accessing using the id.
Our application started on Rails 2.1 and has transitioned through 2.2 and 2.3 with no significant changes to the routing. Sorry I couldn't be more help.
Peer

Resources