beginner question: database relationships

Hi, I'm new to db/web stuff so I have some basic questions. Basic question: I don't know what to add to my existing scaffolding-generated CRUD.

This project requires "Users" who own many unique "Topics". Each "Topic" will contain a "Blacklist" textfile, several "Rawtext" textfiles and several "Webtext" textfiles. Some string-parsing code will use the "Blacklist" file to process the "Rawtext" file, yielding the processed "Webtext" files. So far I have a database with tables for "Users", "Topics", "Blacklists", "Rawtexts", "Webtexts".

I have used scaffolding to generate basic CRUD functionality for each. I have specified the has_many and belongs_to relationships in /app/models.

The "Topic" table contains user_id:integer and searchstring:string attributes. I have manually created a "Topic" entry corresponding to an existing user_id, and modified my user/show.html.erb to display the user's topics.

So, here's my goal: I want an "intuitive" flow of "create user"->"create user's topics" -> "add blacklist for topic". Right now, my "edit user" view doesn't allow adding topics (topics must be added manually, with a known user_id).

Am I going in the right direction? Is there a normal/default way of editing (adding) a table entry's "children"?

Alexander Farley wrote in post #978434:

So, here's my goal: I want an "intuitive" flow of "create user"->"create user's topics" -> "add blacklist for topic". Right now, my "edit user" view doesn't allow adding topics (topics must be added manually, with a known user_id).

So, you want to create a new user and automatically create a topic for that user? Why? Are you just trying to add some seed data for the user?

If so, you can do:

user = User.new(:email => 'bob@example.com', :hashed_password => '...') user.create_topic(... your topic fields ...)

.. that's assuming you have the fields I expressed above.

When a model belongs to another, you automatically get the create_model method..

But, if you aren't trying to automatically populate some seed data, why are you trying to create a topic for a user?

Am I going in the right direction? Is there a normal/default way of editing (adding) a table entry's "children"?

You should check out the methods for the model. Try the following in your rails console:

User.methods.sort.each do |list|   p list end

user = User.new user.methods.sort.each do |list|   p list end

The console is your best friend right now. I would check out the guides on active record so you can gain a better understanding of how to work with database records:

Look over active record associations and active record callbacks.

You can handle the blacklist/raw/etc. that you are trying to work with using before_create and after_create in the topic model. That way when a topic is being created .. something is done.. and after it's created something else is done..

With not too much to go on, this is all I can offer at the moment.

That helps a lot. To clarify, I am not necessarily looking to create seed data upon creation of a User; just trying to figure out how to "link" the creation of the two resources. The create_model method sounds about right.

Anyway, your info gives me plenty to read up on for now. Thanks again

Alex

Alexander Farley wrote in post #978480:

That helps a lot. To clarify, I am not necessarily looking to create seed data upon creation of a User; just trying to figure out how to "link" the creation of the two resources. The create_model method sounds about right.

Anyway, your info gives me plenty to read up on for now. Thanks again

Alex

Hi Alex,

To simplify how you see those methods, you don't necessarily have to create a new user object. You can use:

user = User.first .. and then look through the methods for the user object.

The reason why I supplied two different puts statements is so that you can see the difference between methods for each. One is showing the methods available to the User "class", while the other is showing methods available to the User "object".

Look for build_ methods as well as these will not save the record until you forcibly save the record. It will allow you a little more flexibility with your getting used to the console.

Also notice that the create_ and build_ methods available to the user object are usuable with has_one relationships. While the same methods are usuable with objects from models that have belongs_to relationships.

So, as an example:

has_many :moderators has_many :topics has_many :posts has_one :userprofile

You would see the create_ and build_ methods for a user object only for userprofile.

user = User.first user.methods.sort.each do |method|   p method end

... methods.. ... build_userprofile ... create_userprofile ... etc..

Likewise, for topic, if you had:

class Topic < ActiveRecord::Base   belongs_to :user   #... end

topic = Topic.first topic.methods.sort.each do |method|   p method end

... methods.. ... build_user ... create_user ... etc..

Test out a brief example just to see what happens:

topic.build_user

As for accessing the table data for each model with has_one or has_many from the user model..

topics = User.first.topics

And if you want to iterate over the returned array..

topics.each do |topic|   p topic end

Hey why dont you try out partial view. They heavily solve your problem of user creation and topic addition on the same page itself . You can add the add topic partial they in the edit user said itself thereby solving the problem

Thanks for the advice, follow up questions:

I'm using Devise for authentication. I think this means the controller inside the Devise gem handles user model editing.

So, how does one add Topics as a nested resource for Users? I understand this normally requires three things: a) nested partial form for creating topics owned by users added into the users edit form, b) @user.build_topic added into the Users controller edit action, c) accepts_nested_attributes_for :topics added into User model.

So basically two questions:

  -is it standard practice to have to modify the gem like this (in the Devise controller)? is there a less intrusive way?

  -Are the steps that I required necessary & sufficient?

Ok, so I've discovered that user.topics.build can be done in the User edit form (in my project, not in the gem). However, I'm not sure how to save this newly built topic; normally this would be done by the topic controller catching the POST right? But in this case it's not the topic controller that gets the POST.