shabda
Comments
Reactions

The Rails and Django models layer Rosseta stone

By : Shabda Raaj

Rails Active records and Django models are more similar than they are different. This is a quick guide to converting between Rails 3 and Django 1.2, and is available on github at http://github.com/uswaretech/Acts-as-Django

Defining models

Both Django and Rails keep the canonical database representation in ruby or python.

#Django

class Post(models.Model):
    name = models.CharField(max_length = 100, )
    slug = models.CharField(max_length = 100, )
    body = models.TextField()

class Comments(models.Model):
    post = models.ForeignKey(Post)
    username = models.CharField(max_length = 100, )
    comment = models.TextField()

#Rails

#db/schema.rb
ActiveRecord::Schema.define(:version => 20100319195739) do

  create_table "comments", :force => true do |t|
    t.string   "username"
    t.text     "comment"
    t.integer  "post_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "posts", :force => true do |t|
    t.string   "name"
    t.string   "slug"
    t.text     "body"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

end

#In apps models
class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post
end

The main difference is that Django keeps it one file, while rails has it split over many files. In Django, the foreign key is specified only on the Child model via models.ForeignKey but in Rails both sides of relationship need to be specified via has_many and belongs_to.

Create a object without saving it

In [1]: from blog.models import *

In [2]: post = Post()

In [3]: print post.id
None

irb(main):001:0> post = Post.new
=> #<Post id: nil, name: nil, slug: nil, body: nil, created_at: nil, updated_at: nil>
irb(main):002:0> post.id
=> nil

Set values and save to the database

In [4]: post.name = "Hello"

In [5]: post.slug = "hello"

In [6]: post.body = "Hello, this is a post"

In [8]: post.save()

In [9]: post.id
Out[9]: 1

irb(main):001:0> post = Post.new
=> #<Post id: nil, name: nil, slug: nil, body: nil, created_at: nil, updated_at: nil>
irb(main):002:0> post.id
=> nil
irb(main):003:0> post.name = "Hello"
=> "Hello"
irb(main):004:0> post.slug = "hello"
=> "hello"
irb(main):005:0>  post.body = "Hello, this is a post"
=> "Hello, this is a post"
irb(main):006:0> post.save()
=> true
irb(main):007:0> post.id
=> 2

There is not much to see here, both DJango and Rails create the object in essentially the same way. Until you call save, the objects are not saved to the database.

Find object by the primary key.

In [10]: Post.objects.get(id = 1)
Out[10]: <Post: Post object>

irb(main):008:0> pst = Post.find(2)
=> #<Post id: 2, name: "Hello", slug: "hello", body: "Hello, this is a post", created_at: "2010-03-19 20:11:34", updated_at: "2010-03-19 20:11:34">

What Rails calls find, Django calls get.

More create methods

In [12]: Post.objects.create(name="Hi", slug="hi", body="Hi hi hi.")
Out[12]: <Post: Post object>

irb(main):012:0> Post.create(:name=>"Hi", :slug=>"Hi", :body=>"Hi hi hi")
=> #<Post id: 4, name: "Hi", slug: "Hi", body: "Hi hi hi", created_at: "2010-03-19 20:17:31", updated_at: "2010-03-19 20:17:31">

In [14]: Post.objects.get_or_create(name="Hi")
Out[14]: (<Post: Post object>, False)

irb(main):015:0> Post.find_or_create_by_name("Hi")
=> #<Post id: 4, name: "Hi", slug: "Hi", body: "Hi hi hi", created_at: "2010-03-19 20:17:31", updated_at: "2010-03-19 20:17:31">

You can create in one step without calling save via a create in both Rails and Django. While rails has dynamically named methods, Django accepts named parameters in filter and get_or_create.

More find methods

In [15]: Post.objects.filter(id__in = [1, 2, 3])
Out[15]: [<Post: Post object>, <Post: Post object>]

irb(main):017:0> Post.find(1, 2, 3)
=> [#<Post id: 1, name: nil, slug: nil, body: nil, created_at: "2010-03-19 19:58:31", updated_at: "2010-03-19 19:58:31">, #<Post id: 2, name: "Hello", slug: "hello", body: "Hello, this is a post", created_at: "2010-03-19 20:11:34", updated_at: "2010-03-19 20:11:34">, #<Post id: 3, name: nil, slug: nil, body: nil, created_at: "2010-03-19 20:16:04", updated_at: "2010-03-19 20:16:04">]

In [16]: Post.objects.get(name="Hi")
Out[16]: <Post: Post object>

irb(main):023:0> Post.find_by_name("Hi")
=> #<Post id: 4, name: "Hi", slug: "Hi", body: "Hi hi hi", created_at: "2010-03-19 20:17:31", updated_at: "2010-03-19 20:17:31">

In [17]: Post.objects.all()
Out[17]: [<Post: Post object>, <Post: Post object>]

irb(main):024:0> Post.find(:all)
=> [#<Post id: 1, name: nil, slug: nil, body: nil, created_at: "2010-03-19 19:58:31", updated_at: "2010-03-19 19:58:31">, #<Post id: 2, name: "Hello", slug: "hello", body: "Hello, this is a post", created_at: "2010-03-19 20:11:34", updated_at: "2010-03-19 20:11:34">, #<Post id: 3, name: nil, slug: nil, body: nil, created_at: "2010-03-19 20:16:04", updated_at: "2010-03-19 20:16:04">, #<Post id: 4, name: "Hi", slug: "Hi", body: "Hi hi hi", created_at: "2010-03-19 20:17:31", updated_at: "2010-03-19 20:17:31">]

In [18]: pp = Post.objects.filter(name="Hi")

In [19]: pp
Out[19]: [<Post: Post object>]
In [20]: pp[0]
Out[20]: <Post: Post object>

irb(main):032:0> pp = Post.where({:name=>"Hi"})
=> #<ActiveRecord::Relation:0xb6aedc04 @arel=nil, @select_values=[], @last=nil, @order_values=[], @group_values=[], ...
irb(main):033:0> pp[0]
=> #<Post id: 4, name: "Hi", slug: "Hi", body: "Hi hi hi", created_at: "2010-03-19 20:17:31", updated_at: "2010-03-19 20:17:31">

In [21]: Post.objects.filter(name__in = ["Hi", "Hello"])
Out[21]: [<Post: Post object>, <Post: Post object>]

irb(main):034:0> pp = Post.where({:name=>["Hi", "Hello"]})
=> #<ActiveRecord::Relation:0xb6ae4c6c @arel=nil, @select_values=
....
irb(main):035:0> pp[0]
=> #<Post id: 2, name: "Hello", slug: "hello", body: "Hello, this is a post", created_at: "2010-03-19 20:11:34", updated_at: "2010-03-19 20:11:34">
irb(main):036:0> pp[1]
=> #<Post id: 4, name: "Hi", slug: "Hi", body: "Hi hi hi", created_at: "2010-03-19 20:17:31", updated_at: "2010-03-19 20:17:31">

In [29]: p = Post.objects.filter(name__in = ["Hi", "Hello"]).only("name")

irb(main):041:0> pp = Post.where({:name=>["Hi", "Hello"]}).select("name")

The query capability and syntax are similar with major differences being,

  1. Rails has dynamically named finders, while Django accepts keyword arguments for same.
  2. SQL operators like in are fired by __ in Django, while Rails infers it based on the data type.

Limit, offset and order

In [30]: p = Post.objects.filter(name__in = ["Hi", "Hello"])[:1]

In [31]: p
Out[31]: [<Post: Post object>]

pp = Post.where({:name=>["Hi", "Hello"]}).select("name").limit(1)

irb(main):049:0> pp[0]
=> #<Post name: "Hello">
irb(main):050:0> pp[1]
=> nil

=> #<Post id: 4, name: "Hi", slug: "Hi", body: "Hi hi hi", created_at: "2010-03-19 20:17:31", updated_at: "2010-03-19 20:17:31">
irb(main):067:0> pp = Post.where({:name=>["Hi", "Hello"]}).limit(1).offset(1)

irb(main):067:0> pp[0]
=> #<Post id: 4, name: "Hi", slug: "Hi", body: "Hi hi hi", created_at: "2010-03-19 20:17:31", updated_at: "2010-03-19 20:17:31">
irb(main):068:0> pp[1]
=> nil

In [34]: p = Post.objects.filter(name__in = ["Hi", "Hello"])[1:2]

In [35]: p[0].name
Out[35]: u'Hi'

In [36]: p[1].name
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)

/home/shabda/Code/Django/Weblog/<ipython console> in <module>()

/usr/local/lib/python2.6/dist-packages/django/db/models/query.py in __getitem__(self, k)
    185             qs = self._clone()
    186             qs.query.set_limits(k, k + 1)
--> 187             return list(qs)[0]
    188         except self.model.DoesNotExist, e:
    189             raise IndexError(e.args)

IndexError: list index out of range

In [39]: p = Post.objects.order_by("name")[1:2]

In [40]: p
Out[40]: [<Post: Post object>]

irb(main):069:0> pp = Post.order("name").limit(1).offset(1)

Again fairly similar, both Django and rails provide ordering, offset and limits, while Django does this via array slicing, Rails does this via functions. Also both Django and Rails allow method chaining, and Sql is only evaluated lazily when needed.

Specifying Model associations.

Django: models.ForeignKey
Rails: belongs_to

Django: models.ManyToManyField
Rails: has_and_belongs_to_many

Django: models.OneToOneField
Rails: has_one

Django: No needed
Rails: has_many

Again Rails and Django are similar with Django automatically inferring the reverse relationships.

Polymorphic Associations and Generic Relations

You possibly have pictures in your application which can be attached to any object. Both Django and Rails provide options for it via Polymorphic Associations and Generic Relations

class Picture(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey()

class Article(models.Model):
    body = models.TextField()
    picture =  generic.GenericRelation(Picture)

class BioGraphy(models.Model):
    bio  = models.TextField()
    picture = generic.GenericRelation(Picture)

class Picture < ActiveRecord::Base
  belongs_to :imageable, :polymorphic => true
end

class Employee < ActiveRecord::Base
  has_many :pictures, :as => :imageable
end

class Product < ActiveRecord::Base
  has_many :pictures, :as => :imageable
end

Self Joins

Self joins are a special case of Foreign key where a Object has a relationship to itself. Both Django and Rails handle it normally via their FK mechanisms

class Employee(models.Model):
    manager = models.ForeignKey("self", related_name = "subordinates")

class Employee < ActiveRecord::Base
  has_many :subordinates, :class_name => "Employee",
    :foreign_key => "manager_id"
  belongs_to :manager, :class_name => "Employee"
end

References

guides.rails.info djangoproject.com/documentation/


Related Posts


Can we help you build amazing apps? Contact us today.

Comments

Pour les dames qui adorent Sacs ¨¤ main personnalis¨¦s

The Rails and Django models layer Rosseta stone - Agiliq Blog | Django web app development

commmenttor
Nathaniel

My battery's about to run out http://framedintatnuck.com/term-paper-writing/ to kill a mockingbird free paragraph writing With reasoning and courtesy toward each other, most racial differences could be avoided. Until we stop the eye-for-an-eye mentality, ignore the demagogues and dwell on our sameness, we will keep watching each other with suspicion, and that is the shame of racism.

commmenttor
Riley

magic story very thanks http://framedintatnuck.com/write-my-report-for-me-do-my-homework-for-me/ pay someone to do my research paper The demonstrations turned violent, and on Saturday protesters attacked the Benghazi and Tripoli offices of the Muslim Brotherhood's political party and the headquarters of a liberal political coalition in the capital.

commmenttor
Logan

A few months http://lesterhospitality.com/online-writing-sites/ custom essay cheapest "We have found relevant communications on his electronicmedia, which referenced the delusional belief that he was beingcontrolled or influenced by extremely low frequencyelectromagnetic waves for the past three months," Parlave told anews conference.

commmenttor
Liam

We've got a joint account http://www.djoasis.com/where-can-i-get-someone-to-write-an-essay-for-me/ thesis writing help malaysia At a hearing on Wednesday, U.S. District Court Judge Bernard Friedman scheduled oral arguments in the case for October 1 and told the lawyers he would likely issue a written opinion soon after on the challenge to the constitutional ban, which Michigan voters adopted in 2004.

commmenttor
Joshua

We work together http://framedintatnuck.com/how-much-does-it-cost-to-get-a-business-plan/ discount essays for college The Dow Jones industrial average was down 11.63points, or 0.08 percent, at 15,439.46. The Standard & Poor's 500Index was down 2.96 points, or 0.17 percent, at1,706.95. The Nasdaq Composite Index was up 8.43points, or 0.22 percent, at 3,783.16.

commmenttor
christian louboutin soldes

Louboutin Femme Chaussures Compensés sont vente chaude en 2013. Doté cuir de veau, un talon haut sur ​​11cm. Tous les Louboutin Chaussures Femme Compensés ont été conçus par le maître exceptionnel. Haute cicatrisées Louboutin Femme Chaussures Compensés donner deux pieds dans une belle et sexy, portez.
christian louboutin soldes http://www.gifew.org/wp-pass2.php

commmenttor
Alex

The manager http://framedintatnuck.com/writing-essays-for-high-school-students/ best essay writing software I tried to explain myself, but he was strangely furious (it may have been the gin&hellip;), and so I found someone else to talk to. A year later I was told that on completing his medical training, he had arranged to go straight to Uganda to work as a doctor. The penny dropped, and I realised his formerly unfathomable anger had actually been an expression of his frustration at meeting someone who was doing something similar to what he would like to do himself. The last I heard he was living a very happy and fulfilled life, working in a hospital in Kampala.

commmenttor
Ella

Best Site Good Work http://framedintatnuck.com/writing-comparative-essays/ write my research paper Mayer wrote on her Tumblr blog that Pogue had always been one of her favorite journalists. She said he would publish columns, blog posts and video stories that "demystify the gadgets, apps and technology that powers our users' daily lives."

commmenttor
Ian

This site is crazy :) http://www.inatownthissize.com/research-paper-sale/ help personal statement Johnson talks of a quieter future, of leaving Toronto to set up a rural home in his native Jamaica. He exhibits, as befits a man raised as a devout Christian who once employed a &lsquo;spiritual adviser&rsquo;, a greater inner peace.

commmenttor

Reactions

uswaretech

http://bit.ly/9YB9gJ A comparision and conversion doc between Django and rails models. on github at http://bit.ly/dAQQUg

This comment was originally posted on Twitter

DjangoIreland

The Rails and Django models layer Rosseta stone — The Usware Blog … http://bit.ly/cI5PMY

This comment was originally posted on Twitter

uswaretech_blog

The Rails and Django models layer Rosseta stone: Rails Active records and Django models are more similar than they… http://bit.ly/aRJey3

This comment was originally posted on Twitter

jobboardshq

http://bit.ly/9YB9gJ A comparision and conversion documentc between DJango and Rails models layer. On Github as well at http://bit.ly/dAQQUg

This comment was originally posted on Twitter

thoas

#django models layer in comparison with #rails Active Record http://bit.ly/bXBtZP

This comment was originally posted on Twitter

djangostories

The Rails and Django models layer Rosseta stone: http://bit.ly/d7aq6c

This comment was originally posted on Twitter

bkonkle

A nifty guide to Rails DB model definitions, compared to Django’s model definitions. This will come in handy soon… http://bit.ly/9T1y4P

This comment was originally posted on Twitter

seanodonnell

surprised by how similar ActiveRecord and Django models are http://short.ie/8d04gr

This comment was originally posted on Twitter

johndagostino

The Rails and Django models layer Rosseta stone http://uswaretech.com/blog/2010/03/the-rails-and-django-models-layer-rosseta-stone/

This comment was originally posted on Twitter

PatriceGirard

Model Django vs Active Record de Rails, http://bit.ly/atkFb2.. Pourquoi des ORM pour faire en SQL ce que MongoDB fait nativement?

This comment was originally posted on Twitter

djangostories

The Rails and Django models layer Rosseta stone — The Usware Blog – Django Web Development: http://bit.ly/aWhuzr

This comment was originally posted on Twitter

scalar

a good comparison between rails and django orm layers: http://bit.ly/bup7g6

This comment was originally posted on Twitter

pilhofer

Interesting comparison of Rails & Django models. Coke vs. Pepsi, really. http://bit.ly/9YB9gJ

This comment was originally posted on Twitter

Post a comment Name :

Email :

Your site url:

Comment :

© Agiliq, 2009-2012