Accessing plain old ruby object in Spree 1.1 - ruby-on-rails

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.

Related

Ruby rails not creating instance variables

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>

How to access model-specific constant in routes.rb

I'd like to generate some dynamic routes based on a constant that's stored in one of my models, but I'm getting an error indicating that I don't have access to that constant from the router.
Here's my router snippet:
MyShowroom::CATEGORIES.each do |category|
match "#{category}", :controller => :my_showrooms, :action => :index, :type => category, :as => category
end
Here's the error I'm getting:
NameError: uninitialized constant MyShowroom::CATEGORIES
So basically, I just need to know the proper way to access a model constant in routes.rb
Any help would be much appreciated. Thanks!
Arup gave me the answer I needed to figure out how to implement this (thanks Arup!), but I just wanted to give my own answer to show how this was fully implemented to hopefully help others out.
I left my enum constant defined in my model, because I want to keep things very logically organized (i.e. the enum is directly related to the model so that's where it belongs). To make the constant available across the application, I created a constants.rb file in app/config/initializers and then I created a new constant in that file that simply pointed to the constant I already had defined in my model - effectively making the constant that's defined within my model available across the application.
Here's the full implementation:
my_showroom.rb (Model)
CATEGORIES = {
1 => 'Opinions Please',
2 => 'Budget Minded',
3 => 'Getting Started',
4 => 'Ever Evolving',
5 => 'Done for Now',
6 => 'All Out Assault',
7 => 'Home Theater',
8 => 'Secondary Rigs'
}
constants.rb
MY_SHOWROOM_CATEGORIES = MyShowroom::CATEGORIES
routes.rb
MY_SHOWROOM_CATEGORIES.each do |key, value|
action_name = value.tr(' ', '_').downcase
get "my_showrooms/#{action_name}", to: "my_showrooms##{action_name}"
end
Generated Routes
You can create a file called constants.rb inside the app/config/initializers/ directory. And then you are done to use them anywhere.Then put the module, class or any constants, inside constants that you want to use any places inside your app.

Undefined local variables in Rails 3 partials after upgrade to Ruby 1.9.3

I know there are several posts on this issue but none of the solutions I've read help here.
I've just upgraded from Ruby 1.8.7 to 1.9.3p429 and now, I get undefined local variable in my partials.
I am calling a partial (from a partial in case that's relevant) thusly:
= render :partial => 'user_name', :locals => {:user => item_user, :extra_class => "active"}
In the partial, I access these locals thusly:
- if(current_user and user.silhouette_user_id.to_i == current_user.silhouette_user_id)
= notranslate(current_user.full_name)
- else
- if !local_assigns[:extra_class].nil?
= notranslate(link_to( h(user.full_name), stream_url(:user_id => user.silhouette_user_id), :class => extra_class )) rescue "Anonymous"
- else
= notranslate(link_to( h(user.full_name), stream_url(:user_id => user.silhouette_user_id) )) rescue "Anonymous"
= notranslate(link_to "Pro", "#", :class => "badge badge-pro", :title => "#{user.part_name} is pro") if SSO.is_pro? user
I can access the locals via the local_assigns hash, so if I add these lines to the top, I have access:
user = local_assigns[:user]
extra_class = local_assigns[:extra_class]
I could live with that. However, it gets worse. user is an ActiveRecord model object. I cannot, however, access the attributes of this object with user.attribute notation. Instead I have to user user[:attribute].
I could still get by with this except that some of the attributes of user are actually methods, which I cannot access using user[:method].
I thought it might be the Rails, which was at 3.1.12 so I upgraded to 3.2.13 with no change.
Any ideas? Could it be the HAML processor? All other posts that were solved used ERB.
Try using this way for rendering partials (it's correct way for Rails 3):
= render 'user_name', user: item_user, extra_class: "active"
And access to objects using user and extra_class

Rails, Making a Rails form to save a record to an external db

Rails 2.3.5
I haven't used Rails in awhile and I'm a bit out of practice. For the application I'm working on there is an external db that's scanned by a running process and creates tickets in a ticket system. All I need to do is just save a record there.
I thought I could just connect the db and use a Rails form where I create a new model object and then a form uses that - where submitting the form should just go to a create action in the controller.
The error I'm getting from trying this has me stumped though (undefined method `tam_ticketings_path').
Thanks for any tips or help. I never had to deal with saving a record to a db outside teh application and I'm not sure exactly what I should be trying to do here (save going back to an HTML form and a manual SQL Insert statment).
Thanks!
database.yml:
tam_ticketing_db:
adapter: mysql
database: tam_ticketing_1
model: tam_ticketing
class TamTicketing < ActiveRecord::Base
TamTicketing.establish_connection "tam_ticketing_db"
set_table_name "tickets"
end
Tickets controller method:
def new_ticket
#ticket = TamTicketing.new
new_ticket view:
<% form_for(#ticket) do |f| %>
<%= f.error_messages %>
the error:
Showing app/views/tickets/new_ticket.html.erb where line #1 raised:
undefined method `tam_ticketings_path' for #<ActionView::Base:0x3b01f18>
Extracted source (around line #1):
1: <% form_for(#ticket) do |f| %>
2: <%= f.error_messages %>
3:
4: <p>
When you use form_for(someModelInstance) it will use the path method that goes to the create/update action. Make sure you have properly routed your TamTicketing model using something like this in your config/routes.rb file
resources :tam_ticketings
In Rails 2.3.5 the config/routes.rb should look like this:
map.resource :tam_ticketing
Then restart/start your server and browse your view again.
Also on your controller the proper naming for your action should just be 'new' and not 'new_tickets' inorder to have the above routing work correctly. Otherwise you need to add this:
map.new_ticket 'tam_ticketings/new_ticket', :controller => 'tam_ticketings', :action => 'new_ticket'
map.resource :tam_ticketing
I suggest making sure your controller is named TamTicketings (file name is tam_ticketings) and the action is 'new'

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