Jump to content

The ultimate community for Ruby on Rails developers.


Photo

saving data in two models with nested attributes


  • Please log in to reply
11 replies to this topic

#1 andrewliu

andrewliu

    Signalman

  • Members
  • 17 posts

Posted 21 September 2013 - 04:04 AM

I have a form and there's a nested attribute form within that, and I would like to have that nested attribute form save in the same table as the parent form.

 

I have User table and Business table

 

I currently have this form:

 

<%= form_for @user, :html => {:multipart => true} do |f| %>

  <%= f.fields_for :businesses do |builders| %>
    <%= builders.text_field :name %>
  <% end %>

  <%= f.submit "Save" %>
<% end %>

My controller is this:

def edit
  @user = User.find(current_user.id)
  @profile = Profile.new
  @user.businesses.build if @user.businesses.empty?
end 
 
User Model
class User < ActiveRecord::Base
  has_many :businesses
  accepts_nested_attributes_for :businesses, allow_destroy: true
end

Business Model

class Business < ActiveRecord::Base
  belongs_to :users
end

Currently the form is saving the business name in business table, but I would like to save the business name to user table in a certain column as well.

 

How do I go about targeting the business name field and saving the value into the user table?

 

Thanks

 



#2 james

james

    Guard

  • Moderators
  • 221 posts
  • LocationLeeds, U.K.

Posted 21 September 2013 - 09:53 AM

Your question highlights a possible flaw in your logic.

 

1) If a user has many businesses, which of those business names did you want to save in the users table?

 

2) If a user has only one business then change the relationship to a has_one

 

3) Why do you want to do this?

 

Models are the guardian of all data. Actually that's not true, the database is, so I'll rephrase that. The model is the guardian of all business logic, actually that is still not true but the vast majority of Rails developers don't take advantage of the power of the RDBMS they are using, mostly for the very good reason that not all RDBM's are created equal and tools such as triggers, that are available in something like MySQL are not available in SQLite.

 

So the logic to do this belongs in the model, or possibly in a database trigger. What that logic is, and which model it belongs to depends on the answers to my first 3 questions.


Programming is just about problem solving!


#3 Rowel

Rowel

    Controller

  • Members
  • 109 posts

Posted 21 September 2013 - 02:39 PM

Currently the form is saving the business name in business table, but I would like to save the business name to usertable in a certain column as well.

 

 

 

As James said re #3... why? 

 

I think you should save all "business" related information in the business table, and then just have a business_id in your users table.  

 

If a user is associated with 2 or more businesses, then you'd need to setup your models with the necessary relationships.  



#4 andrewliu

andrewliu

    Signalman

  • Members
  • 17 posts

Posted 22 September 2013 - 06:20 PM

Your question highlights a possible flaw in your logic.

 

1) If a user has many businesses, which of those business names did you want to save in the users table?

 

2) If a user has only one business then change the relationship to a has_one

 

3) Why do you want to do this?

 

Models are the guardian of all data. Actually that's not true, the database is, so I'll rephrase that. The model is the guardian of all business logic, actually that is still not true but the vast majority of Rails developers don't take advantage of the power of the RDBMS they are using, mostly for the very good reason that not all RDBM's are created equal and tools such as triggers, that are available in something like MySQL are not available in SQLite.

 

So the logic to do this belongs in the model, or possibly in a database trigger. What that logic is, and which model it belongs to depends on the answers to my first 3 questions.

 

1. Well eventually I'm going to set up where users can fill more businesses, and that will be saved in the business table. But the data that I want to save in the user's table will be primary business.

 

2. #1 explains my reason why its has_many

 

3. I'm trying to do this because when I'm typing in the business name field, I'm using autosuggest which gets data from Business table. So when other uses have a business to add, they can get help from the autosuggest feature. But when they save, it'll save a record in the business table, so now I'll have multiple same business names in that table. I guess I can eliminate the nested attribute form, and just have a field that'll save the business name into users table inside the :users form, and somehow save that field into the Business table? But if I go this route, I'm not sure how I'll be able to add more businesses (maybe I need to make another table for additional businesses). 

 

I prefer to not have multiple same business names in the Business model

 

Thanks



#5 andrewliu

andrewliu

    Signalman

  • Members
  • 17 posts

Posted 22 September 2013 - 06:49 PM

As James said re #3... why? 

 

I think you should save all "business" related information in the business table, and then just have a business_id in your users table.  

 

If a user is associated with 2 or more businesses, then you'd need to setup your models with the necessary relationships.  

 

 

Yeah this sounds like a good idea, I'd like to do that, but I don't want my business table to have multiple same names when someone saves a business name. How do I set it so it doesn't save duplicates? Also, how do I get my users table to get the business id?



#6 Rowel

Rowel

    Controller

  • Members
  • 109 posts

Posted 22 September 2013 - 08:21 PM

but I don't want my business table to have multiple same names when someone saves a business name. How do I set it so it doesn't save duplicates?

 

 

On your user form, you can have a select box so users can select the company. This select box is filled up with entries in your business table. 

 

It doesn't even have to be a selection box. It could be an autocomplete text field form (via Ajax). User types in the first few characters of a business name and query the database and all matching entries displayed for selection.  

 

User clicks Submit, form gets sent to server. 

 

Process the form. If you use a select box, you already have the business.id available. If you use an autocomplete text field, query the database for an exact match, if found, get the business id.

 

If there is no match, then you know it's a new business entry entered by the user.  Save this info into the business table. 


  • james likes this

#7 andrewliu

andrewliu

    Signalman

  • Members
  • 17 posts

Posted 23 September 2013 - 01:35 AM

I know the process of how the business gets saved, i just don't know the rails best practice to saving this data into the database. I'm just not sure how to do it in the controller to save the business id into the user table and also save a new business name (if there is no duplicate) into the business table, all under the same form



#8 andrewliu

andrewliu

    Signalman

  • Members
  • 17 posts

Posted 01 October 2013 - 06:06 AM

So I'm going through a different method now, and maybe a little simpler, but just can't get it right...

 

I have a form where user inputs their information. But I'd like to also save one of the input field data into another table.
 
I have User table and Business table
 
    <%= form_for @user, :html => {:multipart => true} do |f| %>
      ... some input fields
      <%= f.text_field :company_name %>
      ... more input fields
      <%= f.submit "Save" %>
    <% end %>
My controller is like this:
 
    def edit
      @user = User.find(current_user.id)
      @biz = Business.find_or_create_by_name(params[:company_name])
      @biz.save
    end 
 
Its saving the data in the User's table, but its not saving data into the Business table.
 
When a user saves, I have the parameters:
 Parameters: {"user"=>{"company_name"=>"poortest", "company_street_address"=>"1foo bar"}, "commit"=>"Save", "id"=>"1"}

 

I've also tried: 

Business.find_or_create_by_name(params[:user][:company_name])

But I get error: 

undefined method '[]' for nil:NilClass


#9 james

james

    Guard

  • Moderators
  • 221 posts
  • LocationLeeds, U.K.

Posted 01 October 2013 - 06:28 AM

That makes sense, the edit action is not the action that the form gets posted. There won't be a company_name param passed to the edit action, just the id of the user

So you should move that code to the update action and also possibly to the create action then the

params[:user][:company_name]

will work for you.

 

But a better solution might be to make use of callbacks in the User model on an after_save or after_create or whatever callback suits you most and remove that code from your controller entirely, this will also take care of rake tasks seeds and anything else other than a view that might want to update/create the user as business logic really does not belong in the controller and will also avoid problems like this.

 

Read about AR callbacks here http://api.rubyonrai.../Callbacks.html

 

Hope that helps


Programming is just about problem solving!


#10 andrewliu

andrewliu

    Signalman

  • Members
  • 17 posts

Posted 02 October 2013 - 07:38 PM

Yes! This one works! That makes sense, putting it into update action.

 

I'll also look into callbacks.

 

Thanks



#11 andrewliu

andrewliu

    Signalman

  • Members
  • 17 posts

Posted 03 October 2013 - 05:17 AM

Hello, 

 

I'm not familiar of rails syntax. I was wondering if there's a way to also add the user's id that submitted the form? I already have a column for user's id in Business table, but I'd like to also insert the data along side with the company name. Is this possible?

 

Thanks



#12 james

james

    Guard

  • Moderators
  • 221 posts
  • LocationLeeds, U.K.

Posted 03 October 2013 - 11:44 AM

I think you would benefit from watching a few railscasts

Original

http://railscasts.co...58-token-fields

Updated, only available through subscription (Well worth it IMO)

http://railscasts.co...ciation-revised

I think this one is a must for your scenario

http://railscasts.co...el-form-revised

 

Have a poke around the railscasts site looking particularly for auto complete stuff and active record stuff.

The question you are asking is far too broad to be able to answer accurately.


Programming is just about problem solving!





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users