Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3, how add a associated record after creating a primary record (Books, Auto Add BookCharacter)

Rails newbie... trying to understand the right way to do things...

In my app users can create a Book ( I have that working)

What I want to happen is when a user creates a book, a record is added to the BookCharacters Table, something like (id, book.id, user.id, characterdescription.string.)

When the book is created, the user who created it should automatically be added as the first BookCharacter. After than the user can then manually add/edit as many BookCharacters as they want. But initially I want them added automatically by default.

So in my Book controller I have:

def create
 @book = Book.new(params[:book])
 respond_to do |format|
  if @book.save
....

With Rails, is it the practice to add that kind of logic after the book is saved? Something like

Book.create( :creator => current_user.id)

I appreciate the help

like image 959
AnApprentice Avatar asked Sep 17 '10 21:09

AnApprentice


1 Answers

The important thing to understand is the convention by which Rails implements relationships using ActiveRecord. A book has many characters, and each character belongs to a book, so:

class Book < ActiveRecordBase
  has_many :characters
end

class Character < ActiveRecordBase
  belongs_to :book
end

Rails now assumes that the characters table will have a foreign key called book_id, which relates to the books table. To create a character belonging to a book:

@book = Book.new(:name=>"Book name")
@character = @book.characters.build(:name=>"Character name")

Now when @book is saved (assuming both @book and @character are valid), a row will be created in both the books and the characters tables, with the character row linked through book_id.

To show that a character also belongs to a user, you could add that relationship to the Character model:

class Character < ActiveRecordBase
  belongs_to :book
  belongs_to :user
end

Thus Rails now expects characters to also have foreign key called user_id, which points to a users table (which also needs a User model). To specify the user when creating the character:

@book = Book.new(:name=>"Book name")
@character = @book.characters.build(:name=>"Character name",:user=>current_user)

You can also assign the foreign key by calling the corresponding method on the object:

@character.user = current_user

This all works because it follows the Rails conventions for naming models and tables. You can depart from these conventions, but you'll have a harder time learning Rails if you do.

like image 150
zetetic Avatar answered Sep 21 '22 14:09

zetetic