Ignoring .gitignore - ruby-on-rails

My brother and I are collaborating on an app from two different computers -- one mac and one pc. I can't for the life of me get Postgres to work on his computer, and after a whole bunch of hours, I decided to just have his computer run sqlite3 for development (which is easy as pie), and basically have all the production stuff happen on my mac, while still allowing him to make functional changes from his pc. And merge them to github.
The trouble is, this involves having two different database.yml files, two different db/schema.rb files (I think), and different gemfiles, one with sqlite and the other with pg.
My thought was just to do all that on his computer and add those files to the gitignore file. But if THAT isn't ignored, then when I pull back to my mac, won't I be merging his incorrect configurations to my machine?
At any rate, that's why I was thinking of adding .gitignore to .gitignore. Will this work? Will it create universe-bending paradoxes? Is there a better way to do this that I don't know about?

Are those two schemas really different? They usually aren't.
If they aren't then just ignore config/database.yml and create contig/database_sqlite_example.yml and contig/database_ppostgresql_example.yml. That way, when someone clones repo, he can use SQLite or PostgreSQL by simply copying example file to database.yml (which will be ignored)

No, don't ignore .gitignore
I've always liked the idea of creating local branches for this. I actually go a little local branch crazy... but that's a different issue all together.
If you want to have a private little work bubble then keep your branch local only. You control what gets merged into master (or whatever your development branch is) and you can commit everything in your local branch to git for history sake.
If you want to share what you are working on then just share your branch out. But this way you can keep your environment setups isolated while sharing the local branch so that it is visible for collaboration.
There's plenty of good documentation on Git Branching and Sharing so I'll leave that to you instead of clouding the post with links that surely will get broken.
I'm not sure any of us "really want to" be working directly in the master anyway, especially in collaboration efforts such as yours.

Related

How manage Rails log/development.log with Git(Hub) and multiple users

I am newish to Rails and GitHub and struggling with managing two coders' development logs. Specifically:
How do I merge two developers development logs?
Can I automate their merger? Or can I differentiate them in some Railsy or GitHub Flowy way?
The Rails app I am developing on command line CentOS 6 is being worked on by another developer. We are using a private GitHub repo to help us manage our codebase and are trying to follow The GitHub Flow.
This strategy works well for almost every aspect of our project. The only major problem I've run into with this so far is that our development logs are (of course) out of sync. For instance, he branches from master, then I do. Then he merges to master, then I do, but my merge will fail, citing the automatic merge failure on log/develoment.log. Our logs will be structured like this:
log/development.log - mine
Shared: (Tens of thousands of lines of code from master branch point)
Not: (Thousands of lines of code unique to my branch)
log/development.log - his
Shared: (Tens of thousands of lines of code from master branch point)
Not: (Thousands of lines of code unique to his branch)
So, I find going through this manually, even with diff tools like git mergetool, impractical because of the volumes of code involved. (Am I simply too much of a vim novice to be able to put this to good use? Do others find this trivial?)
Is there a git or rails development strategy we can employ to keep these files without them clashing? (ex: some tinkering with Rails configuration to designate 'Development1' environment vs. 'Development2' environment)?
Is there some command line tool that merges two clashing logs based on time last updated? I'm imaging a tool that, given two clashing git-tracked documents can merge them by comparing the branch point/time, using that as the 'shared' base and adding in the remainder based on which was more recently updated (more recent > appended last). A more advanced version would walk back through commit history to append updates based on commit timestamps.
Logs are useful for your own purposes:
check requests sent
check params sent
check correct matching url/controller-action
check sql queries
check your own stuff (you can log things if you desire)
So because its for your only purpose, no need to pollute your repository with it: add log folder to your gitignore.
There is a recommended gitignore for Rails projects here.
BTW, if logs in console are enough for you, save your disk space and add:
config.logger = Logger.new(STDOUT)
in development.rb

How to organize 50 related rails apps with git?

I'm embarking with 50 related rails apps that will have minor differences between them - the css may differ and maybe each app will have different routes and different titles for the views for the sake of SEO and so on.
But i want all 50 apps to be consistent when i change other things. So basically i will have to end up with my own cms and each website will have different settings.
I'm sure i'm not the first person to encounter this problem. How would i go about organizing this while using Rails, git, github and heroku so that when i deploy, all apps update and remain consistent but still hold their own settings?
I fork a base project and keep it as "upstream".
I clone the forked project in my development environment and keep it as "origin".
So my development environment has an origin and an upstream.
When I do something that effects all forked projects, I do the change in upstream, then I go into each project, pull from upstream and merge.
You can also have a hierarchy of upstreams and keep them synchronized with the original upstream.
If those are purely configuration files, the best approach is to follow the Heroku page "Configuration and Config Vars":
Don't put those files in a Git repo itself.
Use the Heroku CLI’s config, config:add, config:get and config:remove to manage your config vars
I'm a huge fan of only having to maintain one project if it's possible. If it's only the (user-controlled) styling of an app you might go with a multi-tenant approach in the basecamp style. Your app would display different endpoints, e.g. differentiated by subdomains, that you could also point different top-level domains to. The variable parts of the app then needs to be stored in the database, such as e.g. the styles, layouts, and whatever user-controlled content you have. One approach is outlined in the answers to this question, though there are definitely more ways.

How should I use git submodules to share code between Heroku apps?

I have a few Rails 3 apps deployed to Heroku that need to share some business logic. Apparently, although Heroku's Bundler support is pretty solid, it can't yet pull from a private Github repo. So instead I'm building a couple of gems, vendoring them into each app, checking them into git, and pushing them up with the rest of my code.
This has worked alright, but every time I want to change something in these shared gems I have to go to each app, gem unpack to the right directory, git add/git remove all the files that have changed, and so on, and it's becoming a bit of a pain. I may also want to set up different branches of my business logic, and having different applications follow different branches, but I don't know how I'd accomplish that by vendoring.
It looks like git submodules were invented for this kind of situation, but the last time I tried submodules I just found them horribly confusing. I suppose that's what I'd need to do, but the code snippet that Heroku gives as an example at that link is also pretty confusing.
So, my questions:
Are submodules what I want to use here?
What's the simplest possible git workflow I'd need in order to do what I'm describing?
I'm not a beginner with git, but I'm not quite intermediate either, and I want to start with a simple set of steps I can use to learn from. I'd need to track a local git repository from within my vendor/gems directory, pull in updates from that repository regularly, and do so in such a way that Heroku/Bundler doesn't throw a fit when I try to push the entire app to production.
Thank you!
You might find apenwarr’s git subtree command helpful. It provides a nice wrapper around Git’s subtree merge functionality.
Add a new subtree:
git subtree add --prefix=vendor/gems/shiny remote-or-url-to-shiny-gem branch
Pull new commits into the subtree:
git subtree pull --prefix=vendor/gems/shiny remote-or-url-to-shiny-gem branch
You might also like the --squash option if you do not want to incorporate the history.
You can also use git subtree to extract local commits that change the subtree so that they can be pushed to the subtree’s source repository (the split and push sub-commands).
You can use the git-subtree technique
http://progit.org/book/ch6-7.html
As for me, git-subtree was a non sufficient. It required too much tweaking and digging and the result had some annoying flaws and made it look like a bandage. BTW The mentioned apenwarr’s git subtree was last updated two years ago (as to Apr12...) and if git subtree is chosen then i recommend using helmo's fork (or alikes).
I would deifintly recommend using git submodules. Sure, its has some flaws too, but most of them are better handled in later version of git, and you could add some hooks and scripts to make it usable by git newbies. Plus, its far more widely used.
Regarding Heroku, it is now supported. If you need private repositories, Create a user and use its credentials for this purpose and use this format for the repository location:
https://username:password#github.com/user/repo.git
More, For Ruby apps, you can alternately do this with Bundler's :git option.
HTH

How to efficiently handle the changes between production and development when updating from the repository

I have inherited a project with a local development environment that has code specific to that machine, and which is different for the production server. Even though the majority of it is contained in constants and the rest is in the tests, every time I commit from development and update in production I'm going to have to make the same changes in production. Fortunately this is an internal tool with low volume.
I guess I could write a script to automate it but I'm hoping there's a better solution. Anyone else solved this problem?
These questions are similar but not asking the same thing, just so you know I looked:
(1) make changes to a production database
(2) transferring changes from dev to prod
Edit: Nelson LaQuet put me on what I believe is the right track, which led me to Configuring Rails Applications. However, I am unsure how to reference my FormController < ApplicationController constants, such as MyExternalCodeDir, in config/environments/production.rb and config/environments/development.rb.
Also I do not want to be required to change every reference to MyExternalCodeDir to something like config.MyExternalCodeDir.
You abstract all environment settings (database connection/pathing/URIs) into a single file. Let's call it "config.ini"
Then you simply commit a "template" called "config.ini.template" that contains the structure of the config file clearly documenting what is expected at each value - and sensable defaults. You then commit this file.
After you do that, delete the current config.ini file that is specific to your location, and add it to svn:ignore. Now, when you copy and paste config.ini.template to config.ini, and change your settings, it is not going to be committed to the repository.
It adds an extra step per deployment, but must be done only once (unless you add/remove config options). This is the best and most standard way of accomplishing what you want.
I would move the constants' values that are environment specific in a configuration file, which would make it easier to handle. I would also keep the code in just one repository in the version-control system and manage the build outputs in two separate repositories: one for the test environment and one for production. That way I can manage my code base however I choose, and when I want to deploy I'll first commit to test, and then merge from test to production and at that point just diff the configuration file and keep the correct configuration for the production environment.

Managing Rails Migrations for different branches on the same machine

I'm a one-man-band at the company I work for. I develop a Rails application for internal use within the company. Since the beginning of the project I have used SVN for source control and done most, but not all, development in trunk. Occasionally, when I have had very significant changes to make, I have branched and made the changes merging back in when done. All very typical.
However, none of those "significant changes" that I have had to make have ever touched the database migrations. They have always been view/controller stuff.
In this situation, with one development box, how do I play around with migrations and various database changes that I may or may not keep? I don't want to have to remember to revert all the migrations back to the beginning of the branch before I throw the branch out if it doesn't work.
I have considered setting up special development environments and databases (app_branch instead of app_development) but that seems to work strongly against the notion of "easy branching" that experimental development tends to rely on.
Are there best practices for this situation? What are others out there doing in this situation?
I try hard to keep my development database "droppable." If I lose it all - no big deal. My migrations are ready to build it up again from scratch and there's always a script with seed / test data in it somewhere. I guess it's not especially clever.
If I needed a new branch for database work, I would just check it out, drop, create, rake, and then seed. I guess I'd write a script to get it done because when I go to adandon the branch, I'm going to have to go through the same process again from the trunk.
Make sure your schema.rb file is in version control. That way, as you switch branches, you can drop your DB and then do rake db:schema:load as necessary.
Also, you really should switch to Git. It will make branch management a lot easier than SVN. (I speak from lots of experience with both programs.)
Well, if you want to have different schemas, you'll need multiple databases. "Easy branching" refers to source control, typically, and not databases. As far as I know there's no easy way to branch databases like you would branch in, say, git.
One thing we do to manage our dev/production branches is we check our current git branch in our database.yml file. If the current branch is production, we use one database, otherwise we use our dev database. something along the lines of this:
<% if 'git branch' =~ /^\* production/
db = 'production_database'
else
db = 'development_database
end %>
development:
database: <% db %>
Note, the 'production_database' refers to a local version of the production schema, not the live production database.
I wrote a script for dealing with this exact problem. It is based around git, but you could easily change it to work for svn:
https://gist.github.com/4076864
Given a branch name it will:
Roll back any migrations on your current branch which do not exist on the given branch
Discard any changes to the db/schema.rb file
Check out the given branch
Run any new migrations existing in the given branch
Update your test database
I find myself manually doing this all the time on our project, so I thought it'd be nice to automate the process.
If I am creating a branch where you are making siginificant changes, you can create a copy of the database before creating your migrations then change the development section of database.yml inside the branch. Leave your :production section alone and then decide which version of the database you want to keep for future development when you merge the branch back into the trunk.
We do this with feature releases. I'll have local DBs for version 1, 2, 3 like "db_v1", db_v2", etc. As we roll through the versions, each subsequent development branch gets an edit in database.yml while the trunk stays on the last version for bug fixing.

Resources