Ruby on Rails - Polymorphic Association with Categories - ruby-on-rails

I'm currently trying to implement a Category model to my application. I'm trying to design it in a way that Users can have many Categories, and so can Groups.
The problem I'm running into is that I also want to be able to just have a normal list of Categories without them being assigned to any User or Group.
I was referencing rubyonrails.org/association_basics.
class CreateCategories < ActiveRecord::Migration[5.0]
def change
create_table :categories do |t|
t.string :name
t.text :description
t.references :categorizable, polymorphic: true, index: true
t.timestamps
end
end
end
class Category < ApplicationRecord
belongs_to :categorizable, :polymorphic => true
end
class User < ApplicationRecord
has_many :categories, :as => :categorizable
end
class Group< ApplicationRecord
has_many :categories, :as => :categorizable
end
I'm trying to create a new Category through rails c, but whenever I try to save, it rolls back my transaction probably because I'm missing some condition.
Category(id: integer, name: string, description: text, created_at: datetime, updated_at: datetime)
Category.create( :id => 1, :name => 'Category_1', :description => '' )
begin transaction
rollback transaction
I also feel like there is a better way to create a new Category, as I shouldn't be setting the id manually.
Thanks for your help.

In rails 5, whenever you define a belongs_to association, it is required to have the associated record present by default. You would see this when you look at the errors after trying to create the category object
category = Category.create(:name => 'Category_1', :description => '' )
category.errors.full_messages.to_sentence
If you want to be able to save a record without the belongs_to association, you would have to specify it explicitly
class Category < ApplicationRecord
belongs_to :categorizable, polymorphic: true, required: false
end

If you try to create a new category and see the error is that there needs to exists a categorizable record in order for the category to be created, an easy way to do it is to put the new object itself as the categorizable one and it should do the trick.
$ category = Category.new
=> #<Category id: nil, name: nil, description: nil, categorizable_type: nil, categorizable_id: nil, created_at: nil, updated_at: nil>
$ category.save
(0.1ms) begin transaction
(0.1ms) rollback transaction
=> false
$ category.errors.full_messages
=> ["Categorizable must exist"]
$ category = Category.new(categorizable: category)
=> #<Category id: nil, name: nil, description: nil, categorizable_type: "Category", categorizable_id: nil, created_at: nil, updated_at: nil>
$ category.save
(0.1ms) begin transaction
SQL (1.3ms) INSERT INTO "categories" ("categorizable_type", "created_at", "updated_at") VALUES (?, ?, ?) [["categorizable_type", "Category"], ["created_at", 2017-01-15 00:08:55 UTC], ["updated_at", 2017-01-15 00:08:55 UTC]]
(0.7ms) commit transaction
=> true

This should help, Rails Cast on Polymorphic
https://www.youtube.com/watch?v=6l9EAuev16k
You can create polymorphic records with this...
`#category = #categorizable.User.new`
`#category = #categorizable.Group.new`
So you do not need the id.

Related

Adding one-to-many association on namespaced models

I'm trying to set up a one-to-many relationship between two namespaced models, and despite my best efforts can't catch where my problem is.
Here is my migration:
class AddAssociations < ActiveRecord::Migration[5.1]
def change
add_belongs_to :admin_plans, :academy_courses, foreign_key: true, index: true
add_reference :academy_courses, :admin_plans, foreign_key: true, index: true
end
end
Admin::Plan model:
class Admin::Plan < ApplicationRecord
belongs_to :course, class_name: 'Academy::Course', optional: true, foreign_key: :academy_courses_id
end
Academy::Course model:
class Academy::Course < ApplicationRecord
has_many :plans, class_name: 'Admin::Plan, foreign_key: :admin_plans_id
end
Here's what happens when I try to get all plans for a course:
irb(main):001:0> c = Academy::Course.new
=> #<Academy::Course id: nil, title: nil, description: nil, user_id: nil, created_at: nil, updated_at: nil, admin_user_plans_id: nil, admin_plans_id: nil>
irb(main):004:0> c.plans
=> #<ActiveRecord::Associations::CollectionProxy []>
irb(main):005:0> c.plans.all
Traceback (most recent call last):
ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR: column admin_plans.course_id does not exist)
LINE 1: SELECT "admin_plans".* FROM "admin_plans" WHERE "admin_plan...
^
: SELECT "admin_plans".* FROM "admin_plans" WHERE "admin_plans"."course_id" = $1 LIMIT $2
irb(main):007:0> Admin::Plan.last
Admin::Plan Load (1.0ms) SELECT "admin_plans".* FROM "admin_plans" ORDER BY "admin_plans"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> #<Admin::Plan id: 2, name: "MOMLab", price: 15, created_at: "2019-02-06 15:05:43", updated_at: "2019-02-07 07:12:26", academy_courses_id: nil>
I'd really appreciate ideas of where this admin_plans.course_id is coming from, since I declared that the foreign key is :academy_courses_id.
Thanks :)
After a lot of banging my head on the wall and trying every method on Google, I settled for this:
Migration:
class AddCourseIdToAcademyLessons < ActiveRecord::Migration[5.1]
def change
add_column :admin_plans, :course_id, :integer, foreign_key: true, index: true
end
end
Admin::Plan class:
class Admin::Plan < ApplicationRecord
belongs_to :course, class_name: 'Academy::Course', optional: true
end
Academy::Course class:
class Academy::Course < ApplicationRecord
has_many :plans, class_name: 'Admin::Plan'
end

Rails Nested Attributes properly assigning parent_id as index, but isn't assigning additional attributes

I've been working on implementing a new model that belongs to one of our web apps existing models. Eventually, I want to build out a nested form. I understand that the form, and strong params can have it's own suite of issues, but I am currently struggling to get the models to behave as I would expect in the rails console.
Rails 4.2.7, Postgres DB
UPDATE - 10/3/16 - Still trying to find the right solution, but have made some changes
Our work is with Schools and Districts, and this particular case deals with surveys and how a survey is assigned to a school and district. Until now, a survey has been assigned to a district with a SurveyAssignment model, and some down the line logic assumed that all schools in a district were also "assigned" to the survey. Now, we want to be able to add more granularity to the SurveyAssignment and allow some specificity at the school level.
So I created a SchoolSurveyAssignment model and started to get the bits in place.
Here is the relevant model info:
class District < ActiveRecord::Base
...
has_many :schools, dependent: :destroy
has_many :survey_assignments, dependent: :destroy
...
end
class School
...
belongs_to :district
has_many :school_survey_assignments
has_many :survey_assignments, :through => :school_survey_assignments
...
end
class SurveyAssignment
belongs_to :district
belongs_to :survey
has_one :survey_version, through: :survey
has_many :school_survey_assignments, inverse_of: survey_assignment
has_many :schools, :through => :school_survey_assignments
accepts_nested_attributes_for :school_survey_assignments
attr_accessor :survey_group, :survey_version_type, :survey_version_id, :school_survey_assignments_attributes
validates :survey_id, presence: true
end
class SchoolSurveyAssignment
belongs_to :survey_assignment, inverse_of: :school_survey_assignments
belongs_to :school
attr_accessor :school_id, :survey_assignment_id, :grades_affected, :ulc_affected
validates_presence_of :survey_assignment
validates :school_id, presence: true, uniqueness: {scope: :survey_assignment_id}
end
Relevant Controller code:
class SurveyAssignmentsController < ApplicationController
before_action :set_district
before_action :set_survey_assignment, only: [:show, :edit, :update, :destroy]
respond_to :html, :json, :js
def new
#new_survey_assignment = SurveyAssignment.new()
#district.schools.each do |school|
#new_survey_assignment.school_survey_assignments.build(school_id: school.id)
end
end
def create
#survey_assignment = SurveyAssignment.new(survey_assignment_params)
if #survey_assignment.save
flash[:notice] = "Survey successfully assigned to #{#district.name}"
else
flash[:alert] = "There was a problem assigning this survey to #{#district.name}"
end
redirect_to district_survey_assignments_path(#district)
end
def survey_assignment_params
params.require(:survey_assignment).permit(:survey_id, :status, :survey_version_id, school_survey_assignments_attributes: [:id, :survey_assignment_id, :school_id, grades_affected: [], ulc_affected: []]).tap do |p|
p[:district_id] = #district.id
p[:school_year] = session[:selected_year]
end
end
def set_district
#district = District.find(params[:district_id])
end
Here is the relevant schema info:
create_table "school_survey_assignments", force: :cascade do |t|
t.integer "survey_assignment_id"
t.integer "school_id"
t.integer "grades_affected", default: [], array: true
t.string "ulc_affected", default: [], array: true
end
add_index "school_survey_assignments", ["school_id"], name: "index_school_survey_assignments_on_school_id", using: :btree
add_index "school_survey_assignments", ["survey_assignment_id"], name: "index_school_survey_assignments_on_survey_assignment_id", using: :btree
create_table "survey_assignments", force: :cascade do |t|
t.integer "district_id"
t.integer "survey_id"
t.integer "status"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "school_year"
t.integer "last_response_status_id"
end
add_index "survey_assignments", ["district_id"], name: "index_survey_assignments_on_district_id", using: :btree
Once these were in place, I stepped into my rails console and attempted the following:
2.3.1 :002 > sa1 = SurveyAssignment.create(district_id: 3, survey_id: 508, school_year: 2017)
(0.2ms) BEGIN
SQL (0.7ms) INSERT INTO "survey_assignments" ("district_id", "survey_id", "school_year", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["district_id", 3], ["survey_id", 508], ["school_year", 2017], ["created_at", "2016-09-30 21:30:20.205144"], ["updated_at", "2016-09-30 21:30:20.205144"]]
(7.2ms) COMMIT
=> #<SurveyAssignment id: 369, district_id: 3, survey_id: 508, status: nil, created_at: "2016-09-30 21:30:20", updated_at: "2016-09-30 21:30:20", school_year: 2017, last_response_status_id: nil>
2.3.1 :003 > sa2 = SurveyAssignment.create(district_id: 3, survey_id: 508, school_year: 2017)
(0.3ms) BEGIN
SQL (0.4ms) INSERT INTO "survey_assignments" ("district_id", "survey_id", "school_year", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["district_id", 3], ["survey_id", 508], ["school_year", 2017], ["created_at", "2016-09-30 21:30:30.701197"], ["updated_at", "2016-09-30 21:30:30.701197"]]
(0.5ms) COMMIT
=> #<SurveyAssignment id: 370, district_id: 3, survey_id: 508, status: nil, created_at: "2016-09-30 21:30:30", updated_at: "2016-09-30 21:30:30", school_year: 2017, last_response_status_id: nil>
So now, I've successfully created two Survey Assignments. I'm now going to create two School Survey Assignments off of sa1:
2.3.1 :004 > [{school_id: 5}, {school_id: 6}].each do |ssa|
2.3.1 :005 > sa1.school_survey_assignments.create(ssa)
2.3.1 :006?> end
(0.2ms) BEGIN
SchoolSurveyAssignment Exists (2.4ms) SELECT 1 AS one FROM "school_survey_assignments" WHERE ("school_survey_assignments"."school_id" = 5 AND "school_survey_assignments"."survey_assignment_id" = 369) LIMIT 1
SQL (0.4ms) INSERT INTO "school_survey_assignments" ("survey_assignment_id") VALUES ($1) RETURNING "id" [["survey_assignment_id", 369]]
(6.4ms) COMMIT
(0.6ms) BEGIN
SchoolSurveyAssignment Exists (0.4ms) SELECT 1 AS one FROM "school_survey_assignments" WHERE ("school_survey_assignments"."school_id" = 6 AND "school_survey_assignments"."survey_assignment_id" = 369) LIMIT 1
SQL (0.3ms) INSERT INTO "school_survey_assignments" ("survey_assignment_id") VALUES ($1) RETURNING "id" [["survey_assignment_id", 369]]
(0.4ms) COMMIT
=> [{:school_id=>5}, {:school_id=>6}]
2.3.1 :007 > sa1.save
(0.3ms) BEGIN
(0.4ms) COMMIT
=> true
Now, it looks like I've successfully created two SchoolSurveyAssignments with survey_assignment_id = 369 and school_ids = 5 and 6
2.3.1 :008 > sa1.school_survey_assignments
SchoolSurveyAssignment Load (0.3ms) SELECT "school_survey_assignments".* FROM "school_survey_assignments" WHERE "school_survey_assignments"."survey_assignment_id" = $1 [["survey_assignment_id", 369]]
=> #<ActiveRecord::Associations::CollectionProxy [#<SchoolSurveyAssignment id: 5, survey_assignment_id: 369, school_id: nil, grades_affected: [], ulc_affected: []>, #<SchoolSurveyAssignment id: 6, survey_assignment_id: 369, school_id: nil, grades_affected: [], ulc_affected: []>]>
As you can see from the ActivRecord::Associations::CollectionProxy, both of the SchoolSurveyAssignments were created, with survey_assignment_id: 369, but with a nil school_id. This is troubling as it seems to be
Ignoring the parameters being passed into the create function, and
ignoring the validation of school_id
Another item that I don't understand is the following:
2.3.1 :009 > SchoolSurveyAssignment.find(5).survey_assignment_id
SchoolSurveyAssignment Load (0.6ms) SELECT "school_survey_assignments".* FROM "school_survey_assignments" WHERE "school_survey_assignments"."id" = $1 LIMIT 1 [["id", 5]]
=> nil
2.3.1 :011 > SchoolSurveyAssignment.find(5).survey_assignment.id
SchoolSurveyAssignment Load (0.3ms) SELECT "school_survey_assignments".* FROM "school_survey_assignments" WHERE "school_survey_assignments"."id" = $1 LIMIT 1 [["id", 5]]
SurveyAssignment Load (0.4ms) SELECT "survey_assignments".* FROM "survey_assignments" WHERE "survey_assignments"."id" = $1 LIMIT 1 [["id", 369]]
=> 369
Calling .survey_assignment_id should return the attribute on the SchoolSurveyAssignment and give 369. .survey_assignment.id is simply just grabbing the parent object's ID. I would expect both to return the same value, but one returns nil.
The end use case is making a SurveyAssignment form that lets the user set the attributes for a new SurveyAssignment and also set the attributes for X number of SchoolSurveyAssignments (based on # of schools in a district; varies from 2 to 15). Once I get a better grasp on how these models are interacting, I feel confident in executing this goal, but the behavior I'm seeing doesn't make sense to me, and I was hoping to find some clarity on implementing these related models. I feel like I'm bouncing around the answer, but am missing a key detail.
Thanks,
Alex
Try removing your attr_accessor lines of code. attr_accessor shouldn't be used for attributes that are persisted in the database and it's probably messing up the methods that ActiveRecord already provides by default, causing those attributes to not be saved properly
class SurveyAssignment
belongs_to :district
belongs_to :survey
has_one :survey_version, through: :survey
has_many :school_survey_assignments, inverse_of: survey_assignment
has_many :schools, :through => :school_survey_assignments
accepts_nested_attributes_for :school_survey_assignments
validates :survey_id, presence: true
end
class SchoolSurveyAssignment
belongs_to :survey_assignment, inverse_of: :school_survey_assignments
belongs_to :school
validates_presence_of :survey_assignment
validates :school_id, presence: true, uniqueness: {scope: :survey_assignment_id}
end
For the first question, School and SurveyAssignment don't know each other, school_id becomes nil. In your app, these models have m-to-n association indirectly, so how about using has_many through association between models?
In School model, add below:
has_many :survey_assignments, :through => :school_survey_assignments
In SurveyAssignments model, add below:
has_many :schools, :through => :school_survey_assignments
For the last question, both codes seem to be same..

Create two depending models at the same time

I'm trying to model a system where each user may have many emails (at least one).
Following good normalization rules I created two migrations (some fields removed for brevity):
create_table :users do |t|
end
create_table :user_emails do |t|
t.integer :user_id, null: false
t.string :email, null: false
end
add_index :user_emails, :email, :unique => true
add_foreign_key :user_emails, :users, dependent: :delete
and the following rails models:
class User < ActiveRecord::Base
has_many :emails, class_name: 'UserEmail', dependent: :destroy
def self.find_by_email(email)
UserEmail.find_by(email: email).try(:user)
end
validate do
if emails.count < 1
errors.add(:emails, "is empty")
end
end
end
class UserEmail < ActiveRecord::Base
belongs_to :user
validates_presence_of :user_id, :email
validates_uniqueness_of :email
end
Now I am not able to create any of those. User cannot be created since it requires at least an UserEmail. At the same time, UserEmail cannot be created beforehand since it requires an user_id.
I believe I have tried any combination of #user.emails.build and #user.emails << e that I can think of.
How can I solve this really simple problem without renouncing to data consistency (one is saved and the other is not)?
P.s.: I tought that maybe relaxing the validations and using transactions may solve the problem consistently. However I've never used transactions in rails, so any help is really appreciated.
Thanks
validates_presence_of :user_id only check for any valid integer which might not be a valid user.
But if you use validates_presence_of :user and validates_presence_of :emails, they will check the user and emails association are valid and not blank.
Also, when you are trying to create the user and the associated email, you are able to do the following code on application level.
user = User.new(name: 'user name')
user.emails.build(email_address: 'email address') #build(email: '') for your case.
Then, you can save to database with
user.save!
Below is the code I tested with.
class User < ActiveRecord::Base
has_many :emails, class_name: 'UserEmail', dependent: :destroy
validates_presence_of :emails, :message => 'User should have at least one email address.'
end
class UserEmail < ActiveRecord::Base
belongs_to :user
validates_presence_of :user
validates_presence_of :email_address
end
[40] pry(main)> u = User.create!(name: 'doh')
(0.1ms) begin transaction
(0.0ms) rollback transaction
ActiveRecord::RecordInvalid: Validation failed: Emails User should have at least one email address.
[1] pry(main)> u = User.new(name: 'nice')
=> #<User id: nil, name: "nice", created_at: nil, updated_at: nil>
[2] pry(main)> u.emails.build(email_address: 'hello#world.blah')
=> #<UserEmail id: nil, user_id: nil, email_address: "hello#world.blah", created_at: nil, updated_at: nil>
[3] pry(main)> u.save!
(0.1ms) begin transaction
SQL (0.5ms) INSERT INTO "users" ("created_at", "name", "updated_at") VALUES (?, ?, ?) [["created_at", "2014-07-26 10:14:52.184245"], ["name", "nice"], ["updated_at", "2014-07-26 10:14:52.184245"]]
SQL (0.2ms) INSERT INTO "user_emails" ("created_at", "email_address", "updated_at", "user_id") VALUES (?, ?, ?, ?) [["created_at", "2014-07-26 10:14:52.189757"], ["email_address", "hello#world.blah"], ["updated_at", "2014-07-26 10:14:52.189757"], ["user_id", 5]]
(0.7ms) commit transaction
=> true
[4] pry(main)> u.emails.count
(0.2ms) SELECT COUNT(*) FROM "user_emails" WHERE "user_emails"."user_id" = ? [["user_id", 5]]
=> 1
[5] pry(main)> u.id
=> 5
[6] pry(main)> u.name
=> "nice"
[7] pry(main)> u.emails
=> [#<UserEmail id: 4, user_id: 5, email_address: "hello#world.blah", created_at: "2014-07-26 10:14:52", updated_at: "2014-07-26 10:14:52">]
[8] pry(main)> u
=> #<User id: 5, name: "nice", created_at: "2014-07-26 10:14:52", updated_at: "2014-07-26 10:14:52">
[19] pry(main)> UserEmail.create!(email_address: 'test#test.org')
(0.1ms) begin transaction
(0.1ms) rollback transaction
ActiveRecord::RecordInvalid: Validation failed: User can't be blank
Hope this helps.
I just realized that I adding a NOT NULL constraint on the storage layer is sufficient. I can remove the :user_id presence validation and have the same consistency behavior, with the exception that it now works.
However this looks quite hacky from the rails POW. Any better solution is still really appreciated...

has_many association using foreign_key option seem not to work?

I'm new to Rails and I'm having an issue with models using "different" primary/foreign key naming conventions than supported by Rails. (OK, I think this MIGHT be the problem)
So these are my 2 models:
class Project < ActiveRecord::Base
self.primary_key = "PROJECT_ID"
has_many :employees, :foreign_key => "PROJECT_ID"
end
class Employee < ActiveRecord::Base
self.primary_key = "EMPLOYEE_ID"
belongs_to :project, :primary_key => "PROJECT_ID"
end
And this is what's driving me nuts:
> p = Project.find(2)
Project Load (0.2ms) SELECT "projects".* FROM "projects" WHERE "projects"."PROJECT_ID" = ? LIMIT 1 [[nil, 2]]
=> #<Project project_id: 2, name: "Project 2", created_at: "2013-08-18 21:26:33.538007", updated_at: "2013-08-18 21:26:33.538007">
> p.employees.inspect
Employee Load (0.2ms) SELECT "employees".* FROM "employees" WHERE "employees"."PROJECT_ID" = ? **[[nil, nil]]**
=> "#<ActiveRecord::Associations::CollectionProxy []>"
For some reason I don't receive the employees with project_id = 2. It seems that the ? gets substituted with nil.
It works the other way round, check this out
> e = Employee.find_by_project_id(2)
Employee Load (0.2ms) SELECT "employees".* FROM "employees" WHERE "employees"."project_id" = 2 LIMIT 1
=> #<Employee employee_id: 2, first_name: "Will", last_name: "Smith", project_id: 2, created_at: "2013-08-18 21:21:47.884919", updated_at: "2013-08-18 21:22:48.263970">
> e.project.inspect
Project Load (0.2ms) SELECT "projects".* FROM "projects" WHERE "projects"."PROJECT_ID" = ? ORDER BY "projects"."PROJECT_ID" ASC LIMIT 1 [[nil, 2]]
=> "#<Project project_id: 2, name: \"Project 2\", created_at: \"2013-08-18 21:26:33.538007\", updated_at: \"2013-08-18 21:26:33.538007\">"
What am I missing?
Try this:
class Project < ActiveRecord::Base
self.primary_key = "PROJECT_ID"
has_many :employees
end
class Employee < ActiveRecord::Base
attr_accessible :project
self.primary_key = "EMPLOYEE_ID"
belongs_to :project
end
Try to avoid upper case column names at all cost.
for the record here my schema.rb
create_table "employees", :primary_key => "EMPLOYEE_ID", :force => true do |t|
t.integer "project_id"
end
create_table "projects", :primary_key => "PROJECT_ID", :force => true do |t|
end
Try the following:
class Project < ActiveRecord::Base
self.primary_key = "PROJECT_ID"
has_many :employees, :foreign_key => "PROJECT_ID", :primary_key => "PROJECT_ID"
end
class Employee < ActiveRecord::Base
self.primary_key = "EMPLOYEE_ID"
belongs_to :project, :primary_key => "PROJECT_ID", :foreign_key => "PROJECT_ID"
end
If you use uppercased field names (i am not sure based on your question) then make sure you always use uppercased names (e.g. find_by_PROJECT_ID). Rails and ActiveRecord are case sensitive.

Rails 3 Nested Resources and Associations (user_id nil when calling contact.note.create)

(I could probably think of a better title for this and open to suggestions)
I am trying to call this in my NotesController, testing it in rails console:
?> u = User.first
User Load (1.6ms) SELECT "users".* FROM "users" LIMIT 1
=> #<User id: 2, email: nil, password: nil, linkedin_url: nil, created_at: "2012-06-17 05:54:44", updated_at: "2012-06-17 05:54:44", liid: "7fB-pQGIQi">
>> c = u.contacts.first
Contact Load (2.0ms) SELECT "contacts".* FROM "contacts" WHERE "contacts"."user_id" = 2 LIMIT 1
=> #<Contact id: 8, user_id: 2, created_at: "2012-06-19 01:23:45", updated_at: "2012-06-19 01:23:45">
>> c.notes.create!(:body => "this is a note")
(0.5ms) BEGIN
SQL (23.3ms) INSERT INTO "notes" ("body", "contact_id", "created_at", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["body", "this is a note"], ["contact_id", 8], ["created_at", Thu, 21 Jun 2012 05:42:21 UTC +00:00], ["updated_at", Thu, 21 Jun 2012 05:42:21 UTC +00:00], ["user_id", nil]]
(1.7ms) COMMIT
=> #<Note id: 4, created_at: "2012-06-21 05:42:21", updated_at: "2012-06-21 05:42:21", body: "this is a note", user_id: nil, contact_id: 8>
The problem is in the last line where it says that the Note created has a "user_id: nil". I'm wondering what I'm missing that is not allowing the note to properly get the user_id from the contact user_id? I can think of a quick fix, to set the user_id on the note object, but it seems as though it could fetch it from the contact_id, am I wrong?
Here are my models in case this is helpful:
class Contact < ActiveRecord::Base
attr_accessible :user_id
belongs_to :user
has_many :notes
end
class User < ActiveRecord::Base
attr_accessible :password, :liid
has_many :contacts
has_many :notes, :through => :contacts
end
class Note < ActiveRecord::Base
attr_accessible :title, :body
belongs_to :contact
belongs_to :user
end
Thanks for the help!
Your Note also needs to belong to your User:
class Note < ActiveRecord::Base
attr_accessible :title, :body
belongs_to :contact
belongs_to :user
end
Rails will only automatically set the foreign_key of the parent object, and not the parent object's parent like you want. So you'll have to set that attribute manually:
c.notes.create!(:body => "this is a note", :user_id => c.user_id)

Resources