Rails3: How to execute Rails commands (like "rails generate") with shell script - ruby-on-rails-3

I need to be able to generate a model (and later a migration) by executing a Linux shell script.
The script is located directly in the app folder and looks like this:
#!/bin/bash
cd /home/<my_user_profile>/Websites/<my_app_name>
rails g model my_model name:string accepted:boolean [etc...]
The problem is: When I execute the script, the model does not get created. Any ideas why?

Try
exec "rails g model my_model name:string accepted:boolean"

To make sure it's executing in the same context your shell is in, remove the shebang to avoid starting up another bash which may or may not be the same as your current shell.
If you're using rvm/similar, you'd need to either (a) have a default, (b) specify version/gemset, or (c) rely on rvm-like cd fudgery.
Otherwise, should work just fine--it is for me (w/o the shebang, so it'll use whatever current rvm environment I'm in).

Related

Adding a new Migration File using Rake (in the command line)

I know there's a way to automatically create the barebones of a migration file by entering some rake command in the command line but I can't seem to remember exactly what it is. I know it should look something like this...
rake db:create NAME=table_name
but that keeps failing. I also tried
rake db:create_migration NAME=table_name
but no luck with this either. The first attempt returns "Don't know how to build task 'table_name' and the second says "Don't know how to build task 'migration'
rake isn't the command for this, instead you can either:
manually create the file
run rails generate migration table_name in a rails app
or in my case where I'm not using rails, pliny-generate migration table_name

PostgreSQL dump from Ruby on Rails controller

I have implemented ruby on rails app and I want to have a very easy way to create save points and load them from the view of this app.
For now, before I implement a huge undo-stack, I want to do a SQL dump into a file by a ruby on rails controller method and also load the dumped file back into the database. How can I perform this?
First, I wonder what the problem you are actually trying to solve is - maybe something like database transactions would make sense here?
Assuming they don't, however, and you do need to get a full snapshot of the database and restore it, it is going to depend on what database you are using. I'm most familiar with Postgres and I know there exists pg_dump and pg_restore commands to do this type of thing.
https://coderwall.com/p/2e088w/rails-rake-tasks-to-dump-restore-postgresql-databases has a walkthrough of the actual commands needed, and does it in the form of a Rake task. If you are wanting to call it from the controller, however, I would pull those out into a new class that the controller can tell to dump or restore as needed.
Finally I work out an answer, how to dump and restore if you are using a PG Database in Rails.
The problem with pg_restore is that the command cannot drop the database while other users (eg. rails server) are accessing it:
To dump the database:
cmd = "pg_dump -F c -v -U YOUR_ROLE -h localhost YOUR_DATABASE_NAME -f db/backups/hello.psql"
To restore:
system "rake environment db:drop"
system "rake db:create"
system "pg_restore -C -F c -v -U YOUR_ROLE -d YOUR_DATABASE_NAME db/backups/hello.psql"
Finally to get the rake environment db:drop to work you have to use this monkeypatch taken from
# config/initializers/postgresql_database_tasks.rb
module ActiveRecord
module Tasks
class PostgreSQLDatabaseTasks
def drop
establish_master_connection
connection.select_all "select pg_terminate_backend(pg_stat_activity.pid) from pg_stat_activity where datname='#{configuration['database']}' AND state='idle';"
connection.drop_database configuration['database']
end
end
end
end

Is there a better way than this to run an SQL script through puppet?

Take a look at Get puppet build to fail when the contained SQL script fails execution
I was attempting to run a vagrant build which installs Oracle XE in an Ubuntu Virtualbox VM and then runs a an SQL script to initialize the Oracle Schema. The vagrant build is here : https://github.com/ajorpheus/vagrant-ubuntu-oracle-xe. The setup.sql is run as a part of the oracle module's init.pp (right at the bottom or search for 'oracle-script').
When running the SQL script as a part of the vagrant build, I see the following error:
notice: /Stage[main]/Oracle::Xe/Exec[oracle-script]/returns: Error 6 initializing SQL*Plus
notice: /Stage[main]/Oracle::Xe/Exec[oracle-script]/returns: SP2-0667: Message file sp1<lang>.msb not found
notice: /Stage[main]/Oracle::Xe/Exec[oracle-script]/returns: SP2-0750: You may need to set ORACLE_HOME to your Oracle software directory
There were two things that were instrumental in me finding a workaround for the problem:
As suggested in this answer, setting the logoutput attribute to true for the exec block under question immediately showed me the error, whereas before the exec was just failing silently.
It seemed strange that I was able to run the command (sqlplus system/manager#xe < /tmp/setup.sql) after manually logging in as the 'vagrant' user. That suggested that there was something missing in the environment. Therefore, I copied all ORACLE env. vars into the exec as seen on Line 211 here
That worked, however, setting up the env vars manually seems a bit brittle. Is there a better way to setup the ORACLE environment for the vagrant user? Or, is there a way to get puppet to setup the environment for the vagrant user similar to an interactive shell?
If some profile has been set up to give the user a working interactive shell, you should be able to pass your action through such a shell
command => 'bash -i -c "<actual command>"'
As an aside about logoutput, since you mentioned that - the documentation advises that "on_failure" is a sane default, as it will only bloat your output when there are actual errors to analyze. It is the actual default in the latests versions of Puppet.

How to load environment variables in the Rails console?

I think this is a little, easy question!
I'm using .env file to keep all my environment variables, and i'm using foreman.
Unfortunately, these environment variables are not being loaded when running rails console rails c so, i'm now loading them manually after running the console, which is not the best way.
I'd like to know if there any better way for that.
About a year ago, the "run" command was added to foreman
ref: https://github.com/ddollar/foreman/pull/121
You can use it as follow:
foreman run rails console
or
foreman run rake db:migrate
rails does not know about the environmental variables specified in .env file as it is specific to foreman. You need to set the environment explicitly before invoking rails console. Have a look at this question.
I personnaly use dotenv in development and testing environements. With this approach, you don't have to prefix your commands, just call the initializer in your config/application.rb :
Bundler.require(*Rails.groups)
Dotenv::Railtie.load
HOSTNAME = ENV['HOSTNAME']

Default c-shell, change to bash but allow for scp

Hi so I am trying to modify my .cshrc file to make bash my default. It is on a school account so I cannot change the main settings but can change the profile. The problem is that when I use the command:
bash
in my .cshrc it works when I am logging in just fine. But anytime I try to scp files it does not work because it launches the .cshrc and scp gets confused when it changes to the bash terminal.
Does anyone know how to get around this? Possibly launch bash in quiet mode...
In general, you shouldn't do anything that invokes an interactive application or produces visible output in your .cshrc. The problem is that .cshrc is sourced for non-interactive shells. And since your default shell is csh, you're going to have csh invoked non-interactively in a lot of cases -- as you've seen with scp.
Instead, I'd just invoke bash -- or, better, bash -l -- manually from the csh prompt. You can set up an alias like, say, alias b bash -l.
If you're going to invoke a new shell automatically on login (which is still not a good idea), put it in your .login, not your .cshrc.
This is assuming chsh doesn't work, but it should -- try it.