Rails seeds.rb undefined method for custom method - ruby-on-rails

I read a few other posts on this subject and am still confused. In my seeds.rb I call delete and create on the model without any issues... when I get to the custom methods I created I get an undefined method error. The create and delete_all work fine when I comment out the name_gen and ssn_gen rows.
Also, this is Rails 3.1.1 on Ruby 1.8.7
Update: should have also mentioned I get the same issue if I change the create to new and move the name_gen sections to something like #sample_data_set.officialFirstName = SampleDataSet.name_gen
Error: undefined method `name_gen' for #
Command for rake: bundle exec rake db:seed RAILS_ENV=development --trace
seeds.rb
SampleDataSet.delete_all
#sample_data_set = SampleDataSet.new (
:campusNum => "96",
:dateOfBirth => "1981-10-09",
:gender => "M",
:officialMiddleInitial => "L",
:addressLine1 => "PO BOX 9",
:addressLine2 => "",
:city => "WOODLAND",
:state => "GA",
:zipCode => "31836",
:homeAreaCode => "706",
:homePhoneNumber => "6742435",
:homePhoneCountryCode => "US",
:workAreaCode => "706",
:workPhoneNumber => "6742435",
:workPhoneCountryCode => "US",
:usCitizen => true,
:financialAid => true,
:previousDegree => "ADN",
:region => "MAIN",
:program => "AAPSY",
:version => "012",
:team => "TEAM 3236A",
:enrollmentUserId => "SSGROTH",
:revCampusOid => "1627",
:executingUserId => "QROBINSO",
:totalDeclaredExtCredits => "1",
#generating some default values for the gen fields... except IRN
:officialFirstName => SampleDataSet.name_gen,
:officialLastName => SampleDataSet.name_gen,
:enrollAgreeSignDate => Date.today.strftime('%Y-%m-%d'),
:scheduledStartDate => Date.tomorrow.strftime('%Y-%m-%d'),
:ssn => SampleDataSet.ssn_gen.to_s
)
#sample_data_set.emailAddresses = officialFirstName + "." + officialLastName + "#aaaa.phoenix.edu"
,
SampleDataSet model
class SampleDataSet < ActiveRecord::Base
#Random info generation
def name_gen(*prepend)
#Random character generation piece I found on Stackoverflow with 102 upvotes
character_map = [('a'..'z'),('A'..'Z')].map{|i| i.to_a}.flatten
name = (0..8).map{ character_map[rand(character_map.length)] }.join
if prepend.nil?
return name
else
return prepend.to_s + "_" + name
end
end
def ssn_gen
#broke this out as its own method in case someone wants some logic later on
ssn = Random.rand(1000000000) + 99999999
return ssn
end
end

In order to call some method directly on class like that:
SampleDataSet.name_gen
instead of calling it on an instance of that class (as regular methods are called) like that:
a = SampleDataSet.new
a.name_gen
you should define that method as a class method.
You can do it using self.name_gen instead of name_gen in method definition like that:
class SampleDataSet < ActiveRecord::Base
# Random info generation
def self.name_gen(*prepend)
# Random character generation piece I found on Stackoverflow with 102 upvotes
character_map = [('a'..'z'), ('A'..'Z')].map { |i| i.to_a }.flatten
name = (0..8).map { character_map[rand(character_map.length)] }.join
if prepend.nil?
return name
else
return prepend + "_" + name
end
end
def self.ssn_gen
# broke this out as its own method in case someone wants some logic later on
ssn = Random.rand(1000000000) + 99999999
return ssn
end
end

Related

undefined method `values_at' for nil:NilClass when I use WashOut gem

I am new to WSDL.
Code (I have added in the view directly - for test): (Page: http://localhost:3000/ccapis )
require 'savon'
client = Savon::Client.new(wsdl: "http://localhost:3000/ccapis/wsdl")
result = client.call(:fetch_prizes, message: { :gl_id => "123456789" })
result.to_hash
And in the controller:
soap_action "fetch_prizes",
:args => { :gl_id => :string },
:return => [:array]
def fetch_prizes
glnumber = params[:gl_id ]
prize = Prize.where(:gl_id => glnumber)
prize_to_show = []
a_hash = {}
prize.each do |p|
a_hash = { :prize => p.prize.to_s, :score => p.score.to_s, :date => p.round_date.to_s }
prize_to_show.push a_hash
a_hash = nil
end
render :soap => prize_to_show
end
When I try and run this in the Console all are good and I can see the result.to_hash but when I go to http://0.0.0.0:3000/ccapis I get the error that I mentioned above.
Explanation of what I am trying to achieve:
I need to supply a WSDL for a client which fetches all the prizes based on a score.
If My approach is wrong please direct me to a document so I can have a read and get a better understanding. Thanks again.

Calling Model name on it's model

I have an import feature from excel. And I put it on my model which:
def self.import(file, employee_name)
spreadsheet = open_spreadsheet(file)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
category = Category.where(:name => row["Category"]).last
if category.blank?
category = Category.create(:name => row["Category"], :is_active => 1)
end
unit = UnitOfMeasure.where(:name => row["Unit"]).last
if unit.blank?
unit = UnitOfMeasure.create(:name => row["Unit"], :is_active => 1)
end
chart_of_account_id=0
stock_output_account=0
if row["Can Sold"]==1
income_account=1
else
income_account=0
end
if row["Can Purchased"]==1
expense_account=1
else
expense_account=0
end
product = Product.create(:plu => row["PLU"], :plu_night_disc => row["PLU Night Disc."], :name => row["Item Desc."], :min_stock => ["Min. Stock"], :product_type => row["Product Type"], :notes => ["Notes"], :sales_price => ["Sales Price"], :night_disc_price => ["Night Disc. Price"], :bottom_price => ["Bottom Price"], :category_id => category.id, :unit_of_measure_id => unit.id, :chart_of_account_id => chart_of_account_id, :stock_output_account => stock_output_account, :income_account => income_account, :expense_account => expense_account, :can_be_sold => row["Can Sold"], :can_be_purchased => row["Can Purchased"], :employee_name => employee_name, :is_active => 1)
end
end
But when I do my import, it doesn't return any error, but my creation of Product it just skipped (look for the long code), when I try change the Product for example to model Country it inserting to database finely. I do confuse of this behaviour. Please any help. Thanks
This behavior you're getting probably means you have an invalid Product record, and the insertion is failing silently. Try using the create! method instead:
product = Product.create!(...)
This method will raise an error if your model is invalid, with explanations on why. You can use that information to debug your code.
Hope that helps.

Not returning an array - Rails model function

I have a method in my model Post like this:
def self.post_template
posts = Post.all
result = []
posts.each do |post|
single_post = {}
single_post['comment_title'] = post.comment.title
single_post['comment_content'] = post.comment.content
result << single_post
end
# return the result
result
end
In one of my rake tasks, I call the function:
namespace :post do
task :comments => :environment do
comments = Post.post_template
puts comments
end
end
In the console, the return value isn't an Array; instead, it prints all the hashes separated by a newline:
{ 'comment_title' => 'stuff', 'comment_content' => 'content' }
{ 'comment_title' => 'stuff', 'comment_content' => 'content' }
{ 'comment_title' => 'stuff', 'comment_content' => 'content' }
However, when I run this in my rails console, I get the expected behavior:
> rails c
> comments = Post.post_template
-- [{ 'comment_title' => 'stuff', 'comment_content' => 'content' },
{ 'comment_title' => 'stuff', 'comment_content' => 'content' }]
Needless to say, I'm pretty confused and would love any sort of guidance! Thank you.
EDIT:
Seems rake tasks simply print out arrays like this, but when I set the result of my array into another hash, it does not seem to maintain the integrity of the array:
namespace :post do
task :comments => :environment do
comments = Post.post_template
data = {}
data['messages'] = comments
end
end
I'm using Mandrill (plugin for Mailchimp) to create these messages and it throws an error saying that what I'm passing in isn't an Array.
I think that's just how rake prints arrays. Try this:
task :array do
puts ["First", "Second"]
end
Now:
> rake array
First
Second

Refactoring a hash to Object

I have a method that return a Hash and then I write the entries of hash in xml file. Iwant to convert this Hash to an object to store the entry and then write it to xml file...
My current code is like this
def entry(city)
{
:loc => ActionController::Integration::Session.new.url_for(:controller => 'cities', :action => 'show', :city_name => city.name, :host => #country_host.value),
:changefreq => 0.8,
:priority => 'monthly',
:lastmod => city.updated_at
}
end
The write_entry method is inside my writer class that writes this entry to xml file
def write_entry(entry)
url = Nokogiri::XML::Node.new( "url" , #xml_document )
%w{loc changefreq priority lastmod}.each do |node|
url << Nokogiri::XML::Node.new( node, #xml_document ).tap do |n|
n.content = entry[ node.to_sym ]
end
end
url.to_xml
end
Thanks
I might be way off here, but it seems like what you're trying to do is something like this:
First, figure out what makes sense as a class name for your new object. I'm going with Entry, because that's the name of your method:
class Entry
end
Then take all the "properties" of your hash and make them reader methods on the object:
class Entry
attr_reader :loc, :action, :changefreq, :priority, :lastmod
end
Next you need to decide how this object will be initialized. It seems like you will need both the city and #country_host for this:
class Entry
attr_reader :loc, :action, :changefreq, :priority, :last mod
def initialize(city, country_host_value)
#loc = ActionController::Integration::Session.new.url_for(:controller => 'cities', :action => 'show', :city_name => city.name, :host => country_host_value)
#changefreq = 0.8 # might actually want to just make this a constant
#priority = 'monthly' # another constant here???
#lastmod = city.updated_at
end
end
Finally add your XML builder method to the class:
class Entry
attr_reader :loc, :action, :changefreq, :priority, :last mod
def initialize(city, country_host_value)
#loc = ActionController::Integration::Session.new.url_for(:controller => 'cities', :action => 'show', :city_name => city.name, :host => country_host_value)
#changefreq = 0.8 # might actually want to just make this a constant
#priority = 'monthly' # another constant here???
#lastmod = city.updated_at
end
def write_entry_to_xml(xml_document)
url = Nokogiri::XML::Node.new( "url" , xml_document )
%w{loc changefreq priority lastmod}.each do |node|
url << Nokogiri::XML::Node.new( node, xml_document ).tap do |n|
n.content = send(node)
end
end
url.to_xml
end
end
Now that your hash has been refactored, you can update your other class(es) to use the new object:
class WhateverClassThisIs
def entry(city)
Entry.new(city, #country_host.value)
end
end
It's not clear how the XML writer method is being called, but you would need to update that as well to use the new write_entry_to_xml method, passing in the xml document as an argument.

Where to put constants in Rails

I have a few constants which are arrays that I don't want to create databse records for but I don't know where to store the constants without getting errors.
For example
CONTAINER_SIZES = [["20 foot"],["40 foot"]]
Where can I store this so all models and controller have access to this?
I will write my way to you.
class User < ActiveRecord::Base
STATES = {
:active => {:id => 100, :name => "active", :label => "Active User"},
:passive => {:id => 110, :name => "passive", :label => "Passive User"},
:deleted => {:id => 120, :name => "deleted", :label => "Deleted User"}
}
# and methods for calling states of user
def self.find_state(value)
if value.class == Fixnum
Post::STATES.collect { |key, state|
return state if state.inspect.index(value.to_s)
}
elsif value.class == Symbol
Post::STATES[value]
end
end
end
so i can call it like
User.find_state(:active)[:id]
or
User.find_state(#user.state_id)[:label]
Also if i want to load all states to a select box and if i don't want some states in it (like deleted state)
def self.states(arg = nil)
states = Post::STATES
states.delete(:deleted)
states.collect { |key, state|
if arg.nil?
state
else
state[arg]
end
}
end
And i can use it now like
select_tag 'state_id', User.states.collect { |s| [s[:label], s[:id]] }
I put them directly in the model class.
class User < ActiveRecord::Base
USER_STATUS_ACTIVE = "ACT"
USER_TYPES = ["MANAGER","DEVELOPER"]
end

Resources