Search code examples
ruby-on-railsrubyforeign-key-relationship

How do I update a record in a table with current record's id


I'm fairly new to both Ruby and Rails and haven't internalized a lot of it. The problem I'm faced with seems like it should be simple to solve, but alas it is not simple for me. I apologize if some of my terminology is imprecise.

Versions: Rails 4.2.0 | Ruby 2.1

I have models Subject, Post & Synopsis. Posts are nested under Subject, so when I create a Post I'm able to update the posts table with subject_id like so:

def create
    @subject = Subject.find(params[:subject_id])
  @post = current_user.posts.build(params.require(:post).permit(:title, :body))
  @post.subject = @subject
...

A Summary is nested under and belongs to one Post. When creating a Summary I want to update the posts table with summary_id. I just can't wrap my head around how to do it and haven't been able to find out how either on Stack Overflow or elsewhere.

If it were a SQL command, and the id of the current post was 23 and the id of the current synopsis was 9, it would be something like UPDATE posts SET posts.synopsis_id = 9 WHERE posts.id = 23.

The relevant controller, models and schema info are below. Let me know if I need to provide more information.

Controller:

synopses_controller.rb

def create
    @subject = Subject.find(params[:subject_id]) #find the Subject id
    @post = Post.find(params[:post_id]) #find the post id
  @synopsis = Synopsis.new(params.require(:synopsis).permit(:name, :description))
  #UPDATE THE POST WITH SYNOPSIS_ID!
  if @synopsis.save
    flash[:notice] = "Synopsis was saved."
    redirect_to [@subject, @post, @synopsis] #go to the Synopsis page
  else
    flash[:error] = "There was an error saving the Synopsis. Please try again."
    render :show
  end
end

Models:

synopsis.rb

class Synopsis < ActiveRecord::Base
  belongs_to :post
end

post.rb

class Post < ActiveRecord::Base
 has_one :synopsis
 has_many :comments
 belongs_to :user
    belongs_to :subject
end

Schema:

schema.rb

create_table "posts", force: :cascade do |t|
 t.string   "title"
 t.text     "body"
 t.datetime "created_at", null: false
 t.datetime "updated_at", null: false
 t.integer  "user_id"
 t.integer  "subject_id"
 t.integer  "synopsis_id"
end

create_table "synopses", force: :cascade do |t|
 t.string   "name"
 t.text     "description"
 t.datetime "created_at",  null: false
 t.datetime "updated_at",  null: false
end

Solution

  • You could do:

    def create
      # ....
      if @synopsis.save
        @post.update(:synopsis_id, @synopsis.id)
        flash[:notice] = "Synopsis was saved."
        redirect_to [@subject, @post, @synopsis] #go to the Synopsis page
      else
      #....
    end