ActiveAdmin and AssociationTypeMismatch

I’ve spent a few good hours fighting a strange issue in my rails application’s ActiveAdmin module. I couldn’t create an has_many_through association without getting the AssociationTypeMismatch error on create or update of the resource!

Solutions found on the internet involved using elements_attributes instead of elements, adding accept_nested_attributes but nothing seemed to work! The solution turned out to be surprisingly simple.

Here is the example – the code is pretty trivial:

In a User model I have

class User < AR:Base
 has_many :groupings
 has_many :elelements, :through => :groupings
end

In the ActiveAdmin view definition I  have:

form do |f|
 f.inputs "Elements" do
  f.input :elements, :as => :check_boxes, :collection => Element.all
 end
end

To get this to work you MUST add an active admin resource representing the connecting M2M table, in my case called  Groupings. After adding it everything started working!

A small tip: Because u usually don’t want to have that table on your dashboard you can either hide it (set the menu option to false), or remove it from top menu:  menu :parent => “Users” and it will show up as submenu under the users top menu. Nice, clean, and accessible :)

Hope it will save someone some time.

Happy Hacking in 2012

Getting Rails 3.1, mongodb and scaffold generators to work.

This tutorial is using rvm and homebrew to show how to install a fully functional rails 3.1 application on mongodb.

Install mongodb

Extracted from http://www.mongodb.org/display/DOCS/Quickstart+OS+X

brew install mongodb

sudo mkdir /data/db

sudo chown -R username /data

The last step is probably not necessary, but I like being able to access all data dirs as my current user

mongod

Start mongo server

Install ruby 1.9.2, and rails 3.1.0.rc4

rvm install 1.9.2

rvm gemset create rails31

rvm gemset use rails31

gem install rails --pre

Create new rails app

rails new app_name --skip-active-record
cd app_name

echo "rvm 1.9.2@rails31" > .rvmrc

The .rvmrv will automatically switch to proper ruby and gemset when entering the dir.

Setup mongo

Most of the steps are taken from the great mongo guide

config/initializers/mongo.rb

MongoMapper.connection = Mongo::Connection.new('localhost', 27017)
MongoMapper.database = "#myapp-#{Rails.env}"

if defined?(PhusionPassenger)
   PhusionPassenger.on_event(:starting_worker_process) do |forked|
     MongoMapper.connection.connect if forked
   end
end

lib/tasks/mongo.rake

namespace :db do
  namespace :test do
    task :prepare do
      # Stub out for MongoDB
    end
  end
end

Configure your app

Gemfile

source 'http://rubygems.org'

gem 'rails', '3.1.0.rc4'

# Asset template engines
gem 'sass-rails', "~> 3.1.0.rc"
gem 'coffee-script'
gem 'uglifier'

gem 'jquery-rails'

# mongo drivers
gem 'mongo_mapper'
gem 'bson_ext'

group :test do
  gem "rspec"
  gem "rspec-rails"
  gem "factory_girl"
  # Pretty printed test output
  gem 'turn', :require => false
end

config/application.rb

Add inside of class Applicaion < Rails::Application. This will make the generators work

   config.generators do |g|
      g.orm :mongo_mapper    # :active_record
      g.template_engine :erb # :haml
      g.test_framework :rspec, :fixture => true, :views => false
      g.fixture_replacement :factory_girl, :dir => "spec/factories"
    end

Run it all

bundle install

rake test

rails g scaffold User

rake s

Migrating from SVN to GitHub

Good time to migrate

For long time, we’ve been using SVN (svn+ssh) to serve our versioning needs… A centralized repository with development/staging/production branches worked relatively well for us. Managing SVN  on our own is ok when the team is static and when the no of changes is not overwhelming.

Recently though, we are planning to get  other teams to work with us, hence there will be more work related to managing users, branches etc. Therefore, it’s the perfect time to move to github.

Creating an organization’s github account

Creating a new organization requires using a new user account – I didn’t find a way to add a new organization by using my current github account. So I created a dummy github (using my company email) and added my existing github user to the list of organization members. So far so good.

Then I had to upgrade the subscription level to be able to create a private repo – would be great if one small private repo could have been created without providing credit card no – not a big deal though.

Migration

There are some tools out there that are supposed to be able to automatically migrate an svn repo to git. I tried svn2git first, but decided to drop the old svn structure, and use the opportunity to cleanup and improve our current branch structure. I got inspired by “A successful git branch model“. So to start with the migration was as simple as these steps (I can’t embed code snippets in wordpress.com – will have to migrate to self-hosted wordpress.org soon):

  1. create .gitignore
  2. git init
  3. git add app test vendor config public scripts …
  4. git add -f .gitignore  (I want the gitignore to be stored in the project and shared with other users)
  5. git commit -m “My first commit”
  6. If you haven’t created .gitignore before adding the files, you might find lots of .svn/entries in git. Here is how to remove them: find . -type d -name ‘.svn’ -exec git rm -rf {} \;
  7. git remote add origin git@github.com:my_git_user/repo.git
  8.  git push -u origin master
Now we have our code on github.

Getting (auto) Deployment to Work

To get my deployment to work, first I had to give access to staging environment’s users. It’s relatively easy done by uploading the public key to the github (Account Setting/SSH Public Keys) and to add the following code to ~/.ssh/config  (make sure to put the private key there – by mistake I first added the public key and it failed). You can test the connection by running  ssh -vv git@github.com.

New branch structure

The successful git branch model is great,  but now I need to get it working and this capistrano recipe is a good starting point. Instead of branching we use tagging. The local workflow is as simple as:

  1. git checkout -b “changeset1″
  2. <add and change code>
  3. git add <list of files>
  4. git commit -m “New featur in changeset1″
Then to push changes to shared repo we need to: switch to master branch(1), pull the changes(2), merge our change branch(3) and push the changes back(4)
  1. git checkout master
  2. git pull
  3. git merge changeset1
  4. git push
Using capistrano though, we can push the changes to the staging server and to github in one command:
  1. capistrano staging deploy # it creates tag staging-2011.06.13.1
  2. capistrano production deploy -s tag=staging-2011.06.13.1
capistrano deploy task takes care of tagging the master tag, pushing it to github, and deploying to staging server.
Deploying to production uses the tagged version. Thats it.

Summary

In a few hours I managed to setup our company gtihub account, migrate our code from svn to github, prepare new workflow and update our scripts to use it. We have now a repository managed by somebode else, workflow that is more flexible and extensible. I can start focusing on improving the working tasks …

It’s time to start, finally!

This blog has been analyzed, planned, considered, then re-analyzed, and re-planned many times but I didn’t put myself together to actually deliver it… Until now!

I’ve been observing both positive and negative uses of technology, followed many advices and started many projects, but only a few were ever launched…

I think that I’m not the only one who finishes starting something, just to start something else rather than starting to finish and deliver.

In this blog I will focus on delivering. Delivering projects, blog posts, advices, tools and ticks. Everything based on hands-down experience of myself, sometimes spiced with references to better sources of knowledge. I want to use the blog to force myself to stay focussed and efficient, and hopefully to inspire others…

Wish me good luck and welcome to my blog.

Follow

Get every new post delivered to your Inbox.