I've written a basic Rails 3 application that shows a form and an upload form on specific URLs. It was all working fine yesterday, but now I'm running into several problems that require fixing. I'll try to describe each problem as best as I can. The reason i'm combining them, is because I feel they're all related and preventing me from finishing my task.
1. Cannot run the application in development mode
For some unknown reason, I cannot get the application to run in development mode. Currently i've overwritten the production.rb file from the environment with the settings from the development environment to get actuall stacktraces.
I've added the RailsEnv production setting to my VirtualHost setting in apache2, but it seems to make no difference. Nor does settings ENV variable to production.
2. ArgumentError on all calls
Whatever call I seem to make, results in this error message. The logfile tells me the following:
Started GET "/" for 192.168.33.82 at
Thu Apr 07 00:54:48 -0700 2011
ArgumentError (wrong number of
arguments (1 for 0)):
Rendered
/usr/lib/ruby/gems/1.8/gems/actionpack-3.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.erb
(1.0ms) Rendered
/usr/lib/ruby/gems/1.8/gems/actionpack-3.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb
(4.1ms) Rendered
/usr/lib/ruby/gems/1.8/gems/actionpack-3.0.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb
within rescues/layout (8.4ms)
This means nothing to me really. I have no clue what's going wrong. I currently have only one controller which looks like this:
class SearchEngineController < ApplicationController
def upload
end
def search
#rows = nil
end
# This function will receive the query string from the search form and perform a search on the
# F.I.S.E index to find any matching results
def query
index = Ferret::Index::Index.new :path => "/public/F.I.S.E", :default_field => 'content'
#rows = Array.New
index.search_each "content|title:#{params[:query]}" do |id,score, title|
#rows << {:id => id, :score => score, :title => title}
end
render :search
end
# This function will receive the file uploaded by the user and process it into the
# F.I.S.E for searching on keywords and synonims
def process
index = Ferret::Index::Index.new :path => "public/F.I.S.E", :default_field => 'content'
file = File.open params[:file], "r"
xml = REXML::Document.new file
filename = params[:file]
title = xml.root.elements['//body/title/text()']
content = xml.root.elements['normalize-space(//body)']
index << { :filename => filename, :title => title, :content => content}
file.close
FileUtils.rm file
end
end
The routing of my application has the following setup: Again this is all pretty basic and probably can be done better.
Roularta::Application.routes.draw do
# define all the url paths we support
match '/upload' => 'search_engine#upload', :via => :get
match '/process' => 'search_engine#process', :via => :post
# redirect the root of the application to the search page
root :to => 'search_engine#search'
# redirect all incoming requests to the query view of the search engine
match '/:controller(/:action(/:id))' => 'search_engine#search'
end
If anyone can spot what's wrong and why this application is failing, please let me know. If needed I can edit this awnser and include additional files that might be required to solve this problem.
EDIT
i've managed to get further by renaming one of the functions on the controller. I renamed search into create and now I'm getting back HAML errors. Perhaps I used a keyword...?
woot, finally found the solutions....
Seems I used keywords to define my actions, and Rails didn't like this. This solved issue 2.
Issue 1 got solved by adding Rails.env= 'development' to the environment.rb file
Related
Per the Rails 3.2 API Docs, to use different locales for number_to_currency, I need to do the following:
<%= number_to_currency(1234567890.506, :locale => :fr) %>
I was expecting the following output:
# => 1 234 567 890,51 €
Even though I literally use that exact thing within my app and it keeps outputting the following:
$1,234,567,890.51
When I check for the available_locales within my app I get the following:
> I18n.available_locales
=> [:en, :de, :es, :fr, :ja, :pl, :"pt-BR", :ru, :sv, :"zh-CN"]
So it SHOULD work, but it doesn't.
What am I missing?
Update 1
Per #s3tjan's comment, I did some digging in that linked Rails issue and that led me to my application.rb where I discovered I18n.enforce_available_locales = false. I changed that to true and restarted the server.
When I tried the above again, I am now getting this error:
ActionView::Template::Error (:fr is not a valid locale):
Not sure how to fix this.
Update 2
So I just realize that I never had a locale file in my config/locales. What I really want is to use the GBP Pounds for currency, so I added an en-GB.yml file in my config/locales, then I restarted my server and console.
In my application.rb, I have the following:
I18n.enforce_available_locales = true
Then I checked my console and got this:
[1] pry(main)> I18n.available_locales
=> [:en, :de, :es, :fr, :ja, :pl, :"pt-BR", :ru, :sv, :"zh-CN", :"en-GB"]
[2] pry(main)>
So the :"en-GB" was added successfully to my app's load path.
But when I do this in my view:
<%= number_to_currency(1234567890.506, :locale => :"en-GB") %>
This is the error I get:
:"en-GB" is not a valid locale excluded from capture due to environment or should_capture callback
ActionView::Template::Error (:"en-GB" is not a valid locale):
So still not working.
Update 3
My en-GB.yml file was taken directly from https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/en-GB.yml
So it looks exactly like that. Yet I am still getting the same error:
ActionView::Template::Error (:"en-GB" is not a valid locale):
Synopsis:
Remove custom language ymls and add the correct version of the i18n-rails gem. This resolved this special issue.
Original answer:
Ok my guess is that your en-GB.yml is empty. So it actually finds the file and adds the locale in I18n.available_locales BUT this does not include that all translations are available.
When you look at the format of such a yml file you will recognize they all start with
---
language-code
some_keys: ...
This is what actually is loaded into memory and therefore provides all the available translations. Available locale is just defined by found files in config/locales.
When you check the source of number_to_currency It takes the locale from the options and passes it along the key it looks for to I18n.
I18n.translate(:'number.format', :locale => options[:locale], :default => {})
Since you just say that en-GB is available but don't have the actual keys along the locale in memory you get the missing translation issue.
What I suggest is you either use the content of the linked yml file and paste it into your en-GB.yml or you remove your en-GB.yml and find a 3.2 working i18n-rails version and use it. i18n-rails provides plenty of default translations which are utilized all over default rails.
Addition:
Before you added the en-GB.yml file it actually worked like expected.
When no locale is found it defaults to dollar in here since the currency variable will be just and empty {}.
Somehow, I found the solution that worked for me.
First of all, you need to have a locale file with your requirements in it.
Here is the example of fr.yml file
For an instance, copy and paste this file in app/config/locales/
then restart your console,
then try, number_to_currency(1000.51, locale: :fr)
for sure, you will get '1 000,51 €'
Here is the full list of all supported countries' locale file.
Until and unless you don't have locale file with your format required in it, you won't get the desired result.
my rails version is 3.2.22.5, ruby is 2.4.2(I didnt install below 2.x.x)
I use locale yml from
https://github.com/svenfuchs/rails-i18n/blob/rails-3-x/rails/locale/en-GB.yml
This is work well
<%= number_to_currency(1234567890.506, :locale => :"en-GB") %>
<%= number_to_currency(1234567890.506, :locale => "en-GB") %>
to result
£1,234,567,890.51
and I add fr.yml too like
fr:
...
number:
currency:
format:
...
unit: €
And then this is work too
<%= number_to_currency(1234567890.506, :locale => :fr) %>
to result
€1,234,567,890.51
I didn't change or add configuration. I add only controller, view and locale file. And test it.
You could translate directly like, so test this
I18n.translate(:'number.currency.format', :locale => "en-GB", :default => {})
if it occur a same error, then check out you file's name, extension, path.
and you must restart server
Basically, this seems to be https://github.com/rails/rails/issues/7725 reported a year ago by a guy who stopped responding (heh http://xkcd.com/979/)
and I got this when upgrading from the very last Rails 3.0 to Rails 3.2.16.
The route in question serves HTML from model Page on routes of form /en/contact for example (from config/routes.rb)
# pages
STATIC_PAGES.each do |slug, desc|
match ":language/#{slug}" => 'pages#static_page', :defaults => {:slug => slug, :language => 'en'}, :via => :get, :as => slug.underscore.to_s
end
My attempts to make a sample application that does the same thing and breaks have failed (copied relevant parts of the app into a new app, copied the Gemfile & Gemfile.lock and tried to reproduce, all went fine)
This is the stack trace: https://gist.github.com/bbozo/8315184 - not a single line from my app in it
Again, it's one of those argh, a ghost issues, if anyone has a hunch where to hunt for it, you'll make me VERY happy
:-/
Duping the key from hash iterator fixed it for me,
# pages
STATIC_PAGES.each do |slug, desc|
match ":language/#{slug}" => 'pages#static_page', :defaults => {:slug => slug.dup, :language => 'en'}, :via => :get, :as => slug.underscore.to_s
end
problem here was that STATIC_PAGES is a hash constant with String keys, it's keys are frozen. In cases of requests for which route defaults kicked in the router tried to do something with the frozen slug string stored in :defaults => {:slug => slug - something in the rails 3.0 => rails 3.2.16 changelog introduced a modification of this value and shiny exceptions happened in the ActionDispatch stack.
"Unfreezing" slug by doing slag.dup fixed the issue
(Apologies in advance if this question is short on details, I'll watch the comments and add what I can)
I have a Model with the following:
class Product
include Mongoid::Document
include Mongoid::Timestamps
#...
field :document_template, :type => Document
accepts_nested_attributes_for :document_template
Inside the Document document_template, is the following references_many, which I want to modify. Specifically, I want to change which fonts are referenced:
class Document
include Mongoid::Document
include Mongoid::Timestamps
#...
references_many :fonts, :stored_as => :array, :inverse_of => :documents
What sort of logic and details should I have in my controller and form to get this done? Please comment if you would like me to add some of the zany things I've tried; however, I haven't had any luck with any of them.
Here is a quick showing of the issue using rails console:
# Grab a Product and check how many fonts are in it's document_template
ruby-1.8.7-p302 > prod = Product.find(:first)
=> ...
ruby-1.8.7-p302 > prod._id
=> BSON::ObjectId('4d06af15afb3182bf5000111')
ruby-1.8.7-p302 > prod.document_template.font_ids.count
=> 9
# Remove a font from the font_ids array
ruby-1.8.7-p302 > prod.document_template.font_ids.pop
=> BSON::ObjectId('...') # This font id was removed from font_ids
ruby-1.8.7-p302 > prod.document_template.font_ids.count
=> 8
# Save the changes
ruby-1.8.7-p302 > prod.document_template.save!
=> true
ruby-1.8.7-p302 > prod.save!
=> true
# Instantiate a new product object of that same product
ruby-1.8.7-p302 > prod_new = Product.find(:first)
=> ...
# Confirm the _ids are the same
ruby-1.8.7-p302 > prod._id == prod_new._id
=> true
# Check to see if the changes were persisted
ruby-1.8.7-p302 > prod_new.document_template.font_ids.count
=> 9 # If the changes persisted, this should be 8.
# Grrrrr... doesn't look like it. Will the change disappear after a reload too?
ruby-1.8.7-p302 > prod.reload
=> ...
ruby-1.8.7-p302 > prod.document_template.font_ids.count
=> 9
# ಠ_ಠ ... no dice.
Updating objects using mongo (and not mongoid in rails) works as expected.
Kyle Banker has asked for some logging info, so here it is. Unfortunatly, I couldn't find a better source of logging than the output from rails server, which seems to suggest the update call is never being made. For some context here is some info from the controller:
def update_resource(object, attributes)
update_pricing_scheme(object, attributes)
update_document_template_fonts(object, attributes)
end
def update_document_template_fonts(object, attributes)
document_template = object.document_template
document_template_attributes = attributes[:document_template_attributes]
font_ids = document_template_attributes[:font_ids]
font_ids.delete("") # Removing an empty string that tags along with the font_ids.
font_ids.collect! { |f| BSON::ObjectId(f) } # Mongo want BSON::ObjectId
object.document_template.font_ids.replace font_ids
object.document_template.save!(:validate => false)
object.save!(:validate => false)
end
Here is the output from rails server when the POST is processed:
Started GET "/admin/products/4d091b18afb3180f3d000111" for 127.0.0.1 at Wed Dec 15 13:57:28 -0600 2010
Started POST "/admin/products/4d091b18afb3180f3d000111" for 127.0.0.1 at Wed Dec 15 13:57:49 -0600 2010
Processing by Admin::ProductsController#update as HTML
Parameters: {"commit"=>"Update Product", "authenticity_token"=>"QUW0GZw7nz83joj8ncPTtcuqHpHRtp1liq8fB7/rB5s=", "utf8"=>"✓", "id"=>"4d091b18afb3180f3d000111", "product"=>{"name"=>"Ho Ho Ho Flat Multiple Photo Modern Holiday Card", "document_template_attributes"=>{"id"=>"4d091b18afb3180f3d000112", "font_ids"=>["", "4d091b17afb3180f3d000023"]}, "description"=>"", "pricing_scheme_id"=>"4d091b17afb3180f3d00003b"}}
development['users'].find({:_id=>BSON::ObjectId('4d091b17afb3180f3d00009b')}, {}).limit(-1)
development['products'].find({:_id=>BSON::ObjectId('4d091b18afb3180f3d000111')}, {}).limit(-1)
development['pricing_schemes'].find({:_id=>BSON::ObjectId('4d091b17afb3180f3d00003b')}, {}).limit(-1)
MONGODB development['products'].update({"_id"=>BSON::ObjectId('4d091b18afb3180f3d000111')}, {"$set"=>{"updated_at"=>Wed Dec 15 19:57:50 UTC 2010}})
in Document#set_default_color_scheme: self.color_scheme = #<ColorScheme:0xb52f6f38>
MONGODB development['documents'].update({"_id"=>BSON::ObjectId('4d091b18afb3180f3d000112')}, {"$set"=>{"color_scheme_name"=>"green_charcoal_black", "updated_at"=>Wed Dec 15 19:57:50 UTC 2010}})
Redirected to http://localhost:3000/admin/products/4d091b18afb3180f3d000111
Completed 302 Found in 49ms
It looks like the MONGODB command to update the font_ids is completely absent...
I'm partial to believing Mongoid Issue #357 is causing the problem. The logging above suggests that an update for the product's document_template.fonts (or font_ids) which seems to match the bug description.
(sidenote: I'm a bit confused where exactly the font_ids array comes from if not the :stored_as => :array. I'm not 100% certain which I should be modifying either but since font_ids is an Array and fonts is a Mongoid::Criteria, the path of least resistance is font_ids.)
From a data standpoint, :field and :embeds_* seem to be similar in that the information is embedded in the parent document.
Mongoid has a complicated back end. Therefore, the easiest way to diagnose this is to enable the driver's logging. Then we can look at the exact messages being sent to the database in both cases, and we're sure to get an answer.
Can you attach a logger when you connect to MongoDB and then post the relevant sections of log output?
My application stores a lot of XML files. A background job periodically sends some of those XML files to a specific mailbox. The mailer code is dead-simple:
class MailSender < ActionMailer::Base
default :from => AppConfig.mail_from
smtp_settings :address => AppConfig.smtp_host,
:username => AppConfig.smtp_user,
:password => AppConfig.smtp_pass
def send_xml(record)
f = record.filename.gsub("\\", "/") # converts \ to /
f_short = arq.gsub(/.*\//, "") # extracts only the filename
f_phys = "#{AppConfig.xml_root}#{arq}" # builds the physical filename
headers["Return-Receipt-To"] = AppConfig.return_receipt
attachments[f_short] = File.read(f_phys) if File.exists?(f_phys)
mail :subject => "...",
:to => AppConfig.mail_to
end
end
However, for some reason, those XML are getting corrupted on transmission: the first line break gets added at column 987, and the following are added at column 990. After each break, a space is inserted. I think the picture says for itself:
col 1 col 990
|.................................................|
<?xml version="1.0" ... </IE><IM>321505493301<
/IM><CNAE>4744001< ... 00</pCOFINS><vCOFINS>0.00
</vCOFINS></COFINS ... /prod><imposto><ICMS><ICM
S40><orig>0</orig> ... <infAdic><infCpl>Permite
I tried calling File.read myself on rails console, it works fine, no line breaks are added. So I assume the error should lie on the ActionMailer. Any tips?
Edit for clarification: Most of the XML document lie on a big, single line. I can't change it, since the XML are digitally signed - any change, including adding line breaks and indentation, breaks the digital signature.
Answering the question that gave me the 'Thumbleweed' badge :)
I ended up encoding the file myself, and it's now working fine:
attachments[f_short] = {
:encoding => 'base64',
:content => Base64.encode64( File.read(f_phys) ).chomp
} if File.exists?(f_phys)
I'm trying to get someone else's app up and running on my development laptop but I ran into a routing issue and I'm not sure how to debug it. For a particular controller/action, it just hangs and doesn't time out and there is no error message in the development log. Does anyone know how I can debug this? Thanks.
Edited per comments.
config.rb
ActionController::Routing::Routes.draw do |map|
map.signup "/signup", :controller => "business_accounts", :action => "new"
map.resources :beta_signups, :controller => 'public/beta_signups'
map.root :controller => "public/pages", :action => "index"
end
For brevity, I commented out the rest of the routes and left in a couple of routes that work. The one that failed is the signup route, it simply hangs and never times out.
Here's are the relevant output from the development.log showing a route that works (root) and one that doesn't (signup)
Parameters: {"action"=>"index", "controller"=>"public/pages"}
Rendering template within layouts/public
Rendering public/pages/index
Completed in 672ms (View: 656, DB: 15) | 200 OK [http://localhost/]
SQL (0.0ms) SET client_min_messages TO 'panic'
SQL (0.0ms) SET client_min_messages TO 'notice'
Processing BusinessAccountsController#new (for 127.0.0.1 at 2010-04-22 10:01:30)
[GET]
Parameters: {"action"=>"new", "controller"=>"business_accounts"}
Not sure if this makes any difference but it is running on thin and bundler.
Stripped the controller down to the bare minimum and still getting the same error
class BusinessAccountsController < SSLController
def new
logger.debug "here"
end
end
And I just noticed SSLController, hmm, I need to look into that.
Son of a !#%$##%$%!$#!%, SSLController was my problem, there is no SSL setup on my laptop and the net effect is the app hanging with no error message. Changing it to ApplicationController works. Thanks #Taryn, it was your request that made me looked closer at the code, funny how I've looked at it for days and never saw it till now.