I'm attempting to generate a scaffold but generating it I receive the following error:
rails generate scaffold foo
invoke active_record
The name 'Foo' is either already used in your application or reserved by Ruby on Rails. Please choose an alternative and run this generator again.
Is there a command to find out exactly where this name is being used within my application?
I don't think there is a way to find the file or source of any object/class/module. Also rails has open class concept so the class can be defined or refined in many files so we can not track the same.
but you can check if the name is exist for any object by following
Module.constants.include? "Foo"
Using rubymine, there are a few ways you can do this. There is a "find usages" command that will find all location where a method, variable, etc. are used. There is a "jump to declaration" which in your case would be useful. It will jump to the spot where something is defined. (a class, module, variable, method). there is also a powerful search feature. In this case, search in path would allow you to search the entire application (including external gems being used). You can force case sensitivity on your search to only yield class / module names etc.
Szuper tricky! For me the model name was stuck in memory in the Spring cache system. Had to kill the spring process to free it up.
Look for this when you attempt the command:
Running via Spring preloader in process 57104
Expected string default value for '--serializer'; got true (boolean)
invoke active_record
The name 'Admin' is either already used in your application or reserved
by Ruby on Rails. Please choose an alternative and run this generator
again.
If you see that Spring comment, try looking for spring in your processes and killing:
ps -ef | grep spring
find the id:
501 54701 30654 0 1:43PM ?? 0:04.83 spring app | server | started 8 mins ago | development mode
501 30654 1 0 Tue03PM ttys000 0:03.82 spring server | server | started 142 hours ago
and kill
kill 30654
Thats just one of the given possibilities! Foo is a reserved Word. Ruby also reserves words that arent used as a Model/Module name already. For example you also cant create a model called Configuration eaven there is no class thats clled Configuration.
Related
rails console by default boots with context.back_trace_limit=16, which can be changed to whatever you want simply by typing context.back_trace_limit=n. The problem is you have to type it each time you boot rails c. Where do I change the context.back_trace_limit permanently? Some more reading on rails console configuration appreciated.
You have to create/edit your ~/.irbrc with the following:
IRB.conf[:BACK_TRACE_LIMIT]= 20
To be taken into account:
The options must be uppercased
This option is changing not only the
rails console, but the normal "irb" behavior (the rails console uses
irb to run)
This setting is global, and not per project
Reference http://rakeroutes.com/blog/customize-your-irb/
Update for Rails 5
In Rails 5 the command context.back_trace_limit=20 will fail.
In the console you need to use the command conf.back_trace_limit = 10 for the current session.
For permanent changes, writing IRB.conf[:BACK_TRACE_LIMIT]= 20 in your ~/.irbrc is still valid.
You can see the current settings by calling conf
I'm using ruby standard logger, I want rotational daily one, so in my code I have :
Logger.new("#{$ROOT_PATH}/log/errors.log", 'daily')
It is working perfectly, but it created two files errors.log.20130217 and errors.log.20130217.1.
How can I force it to create just one file a day ?
Your code is correct for a long-running application.
What's happening is you're running code more than once on a given day.
The first time you run it, Ruby creates a log file "errors.log".
When the day changes, Ruby renames the file to "errors.log.20130217".
But somehow you ran the code again, perhaps you're running two apps (or processes, or workers, or threads) that use similar code, and your logger saw that the file name "errors.log.20130217" already existed.
Your logger didn't want to clobber that file, but still needed to rename "errors.log" to a date, so the logger instead created a different file name "errors.log.20130217.1"
To solve this, run your code just once.
If you're running multiple apps called "foo" and "bar" then use log file names like "foo-errors.log" and "bar-errors.log". Or if you're using multiple workers, give each worker its own log file name (e.g. by using the worker's process id, or worker pool array index, or however you're keeping track of your workers).
If you really want to solve this using the Ruby logger, you'll need to override the logger #shift_log_period so it doesn't choose a ".1" suffix. You could subclass Logger and write your worn #shift_log_period to detect that there is an existing log file for the date, and if so, use it instead of doing the file rename.
This is the code causing it from the logger:
def shift_log_period(period_end)
postfix = period_end.strftime("%Y%m%d") # YYYYMMDD
age_file = "#{#filename}.#{postfix}"
if FileTest.exist?(age_file)
# try to avoid filename crash caused by Timestamp change.
idx = 0
# .99 can be overridden; avoid too much file search with 'loop do'
while idx < 100
idx += 1
age_file = "#{#filename}.#{postfix}.#{idx}"
break unless FileTest.exist?(age_file)
end
end
#dev.close rescue nil
File.rename("#{#filename}", age_file)
#dev = create_logfile(#filename)
return true
There is no solution (AFAIK) using the Ruby logger, with its built-in rotator, to manage logs written by multiple apps (a.k.a. workers, processes, threads) simultaneously. This is because each of the apps gets it own log file handle.
Alternatively, use any of the good log rotator tools, such as logrotate as suggested by the Tin Man user in the question comments: http://linuxcommand.org/man_pages/logrotate8.html
In general, logrotate will be your best bet IMHO.
So, i'm building a small application using Rails. I need to use XMPP proto for notification of users with a bit of commands to change user status.
Previous version was an application using plain Python(pretty ugly app) with plain SQL request into DB. There was a table "jabber_queue", so in separated script, bot was checking each second for any rows, processing it(sending message), deleting. It was simple and stupid, but it was ok.
Now i see, i need to integrate this bot functionality into Rails(at least to work with RSpec).
This is my few versions of how it can be done:
Use separated async queue solution. For example, Resque. Use separated Ruby script and push events into Resque, pop events in application(not dependent on DB, so easily fit with RSpec tests and test DB). But it makes my application a bit bloated - i need to use second DB with a lot of memory and CPU additional requirements - it will be overhead for my problem. Also, i don't want to support additional "thing" for this application, i know, it can be done a lot easier way.
Use delayed_job(queue solution using current AR DB). But i don't know how to get current AR DB of Rails application in separated script. Anyway, it's a dirty and ugly way.
Launch XMPP bot WITHIN Rails application, as background worker. So worker will get access to "current" AR(in case of testing, to test-DB). But i simply don't know how to do it. I've found a Navvy, but i need to put somewhere at Rails start a string like a "Navvy::Job.enqueue(Cow, :speak)", i don't know where will be best place for this, to start it with RSpec testing and "rails server". Also, there is a BackgrounDRb, but this project is similar to Navvy and inactive too. Using search on stackoverflow, i've found similar problem to mine, but solution leads me to background_job, which can just anything in background, but i still don't know how to get current AR DB access in separated script.
I'm so sorry for this amount of words in my problem, it's just a brainstream. I see some solutions, but i really need advices and some words from more experienced developers.
So, this was solved using yes, third way.
I've created a class for dealing with bot commands and AR models - awesomo.rb. Nothing special, really. I put this in /lib/ of Rails project. Secondly,
Created configuration file for easy setting of password and JID - config/awesomo.yml
development:
xmpp_jid: ...
xmpp_password: ...
I've created a daemon for my bot - awesomo_daemon.rb. Same, in /lib/. This is what it contains:
#preload rails environment
require File.expand_path(File.join(File.dirname(__FILE__),
'..', 'config', 'environment'))
#load xmpp bot class
require 'awesomo_daemon'
#load xmpp bot configuration file for current environment
AWESOMO_CONFIG = YAML.load_file(File.join(File.dirname(__FILE__),
'..', 'config', 'awesomo.yml'))[Rails.env]
#apply configuration before singleton will be initiated
Awesomo.setup AWESOMO_CONFIG['xmpp_jid'], AWESOMO_CONFIG['xmpp_password']
loop {
Awesomo.instance.idle
sleep 1
}
Created daemon script starter- script/awesomo.
#!/usr/bin/env ruby
require 'rubygems'
require 'daemons'
Daemons.run "lib/awesomo_daemon.rb", dir_mode: :normal,
dir: File.join(File.dirname(__FILE__), '..', 'tmp', 'pids')
Simply run it with command script/awesomo start.
And I can use any my models within awesomo.rb! Also, for queue, i'm using little model - XMPPJob with fields jtype(for example, "xmpp_message"), body("hey!"), to("john#jabber.com"). Fetching it within awesomo.rb idle function of bot class with limit(5).each do |job| case jtype ....
To post any new job for my "awesomo", i'm using function send_message:
def self.send_message to, body
xmppjob = XmppJob.new :jtype => "xmpp_message", :body => body, :to => to
xmppjob.save
end
Everything works perfectly, except XMPP library(xmpp4r-simple) itself, but I'll rewrite it soon using just xmpp4r.
Can rails 3.1 engines have their own databases and at the same time also have access to the database of the main app, for example for user authentication
How can i configure this if possible?
thanks
Yes, they can. I have built engines that use a separate sqlite3 database. This way all the engine's functionality and data is isolated. Remove the engine, remove the database, and everything is gone without leaving a trace.
First of all it's preferred that you generate a mountable engine. This creates a namespace and isolates the engine from your main app. It's not a requirement, but a best practice. I assume you've done in the examples that follow.
At one point you are going to generate a model inside your engine. In the engine root path, type something like this:
$ rails generate resource Post
This will generate the Post controller, model and route. Everything's perfect except for the database migration. You're going to delete this. This migration is useless if you want to keep your data separate. The only goal of migrations inside engines is to have them copied over to the main app's database. So go ahead and get rid of it:
$ rm -r db
Now hook up your root route and controller, like usual.
There's one more change to make inside the model, to make it connect to a separate database.
module YourEngine
class Post < ActiveRecord::Base
establish_connection :adapter => 'sqlite3', :database => 'db/your_engine.sqlite3'
end
end
This way the engine's model will not use the main database, but the one you define. The key to understand is that the database file does not live inside the engine! This database file lives inside the host application. Since you are keeping everything separate, you must create this database by hand. Using the sqlite3 command-line tool and a hand-crafted create statement is quickest:
$ cd "the root dir of the host rails app"
$ sqlite3 db/your_engine.sqlite3
from where you create the table:
CREATE TABLE your_engine_posts (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name varchar(255) NOT NULL DEFAULT '', body text, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL);
Presto! Now it's just a matter of mounting the engine inside your app, boot it and it should all be ready to roll. Obviously now that your engine has a separate database, it's no use working with migrations. You will have to update the schema by hand.
If you're worried about table names clashing with the app you can use the 'isolate_namespace' method. This will prefix all your table names with the namespace of your Engine.
Rails Casts just had a good tutorial which uses this, you should check it out.
http://railscasts.com/episodes/277-mountable-engines
Yes they can.
I wrote a guide on this here
http://railsforum.com/viewtopic.php?id=42143
I'm looking for a way to supply an argument to a ruby on rails project at runtime. Essentially, our project uses public key cryptography to encrypt some sensitive client data and we want the ability to supply the password to the private key file at runtime.
Any Ruby script has access to local environment variables through the ENV hash.
puts ENV['PATH']
So with any posix system (Linux, Unix, Mac OS) you can simply set it when calling the script, like this:
MY_ARG=supersecret ruby script.rb
The same is also valid for rails. If you put puts ENV['MY_ARG'] in your environment.rb and start your server:
$ MY_ARG=supersecret mongrel_rails start
** Starting Mongrel listening at 0.0.0.0:3000
** Starting Rails with development environment...
supersecret
** Rails loaded.
** Loading any Rails specific GemPlugins
** Signals ready. TERM => stop. USR2 => restart. INT => stop (no restart).
** Rails signals registered. HUP => reload (without restart). It might not work well.
** Mongrel 1.1.5 available at 0.0.0.0:3000
** Use CTRL-C to stop.
An environment variable is by far the simplest solution in my opinion.
An easy way to do this would be to create a Rails plugin that takes arguments using 'gets' in its 'init.rb'. Allow me to cook-up a quick code sample:
Make a directory: '$railsRoot/vendor/plugins/startup_args/lib'
Create an object to store argument data in '$railsRoot/vendor/plugins/startup_args/lib/startup_args.rb':
module StartupArgs
##argHash = {}
def self.setArg(key, value)
##argHash[key.to_sym] = value
end
def self.getArg(key)
return ##argHash[key.to_sym]
end
end
Load the StartupArgs module into the Rails project's namespace and populate it with arguments in '$railsRoot/vendor/plugins/startup_args/init.rb':
require "startup_args"
promptString = "Enter arg name (type nothing to continue):"
puts promptString
while (newArg = gets.chomp) != ""
puts "Enter value for '#{newArg}':"
newVal = gets.chomp
StartupArgs.setArg(newArg, newVal)
puts promptString
end
Now, during the Rails project's start-up process, it will try to take key-value pairs from the console. These pairs will be stored in the global-namespace object StartupArgs for later access (via 'StartupArgs.getArg()').
If you anticipate that your Rails project might be deployed in scenarios where the daemon will not have access to the console during startup-time, you could read from a named-pipe instead of the console's standard input.
Going one step further, you could remove all parts of 'init.rb' except for the 'require' statement and add an action that performs this setup to a controller that would take the relevant parameters as a post over the web. Make sure to configure Rails to prevent potentially sensitive parameters (e.g. passwords) from being entered into log files recording accesses or errors (especially if it might be used as an HTTP GET, with parameters in the URL).
(You get the same effect this way as with the system described above if you configure your other Rails actions to ignore requests until the setup action has stored the appropriate parameters to the global object.)
A Note For Micah: I don't have the reputation to comment directly on your post, so I will include my comment here. There might be a few reasons to consider a system that never requires the password to be represented in the filesystem. For example, a developer might be planning a Rails project that could be deployed on varying operating systems and in varying environments. If the developer determines that there could be scenarios in which an administrative or root user could be compromised, cannot be trusted, or cannot be asked to sign confidentiality and security agreements, the developer might decide to add the additional obfuscation of placing the password in memory only (in the interest of requiring a slightly less secure system or a slightly more clever attack to steal the password). Perhaps it could be considered a matter of relative costs: at low cost, the password can be hidden in a way that requires more expensive knowledge in order to retrieve.
What is wrong with putting the password in a file that is chmod'ed to only be readable by the web server user?