0

Originally I had a Joke.rb model that belonged to User model. Joke table had :joke, :author. It worked perfectly when using @joke = current_user.jokes.new(joke_params) but I took the :author out of the Joke model and made it its own model so I can make vanity url's / dynamic routes for each author, when a joke is created by the user. Here's what I have now:

User Model:
has_many :jokes

Joke Model:
belongs_to :user
has_one :author

Author Model:
has_many :jokes

Here's my Schema:

ActiveRecord::Schema.define(version: 20170703173447) do

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

  create_table "jokes", force: :cascade do |t|
    t.string   "joke"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer  "user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

end

And here's my Joke controller:

class JokesController < ApplicationController
  before_action :set_joke, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, except: [:index]

  def index
    @joke = Joke.order("Random()").first
  end

  def my_jokes
    @jokes = current_user.jokes.all
  end

  def new
    @joke = current_user.jokes.new
  end

  def create
    @joke = current_user.jokes.new(joke_params)
    if @joke.save
      redirect_to root_path, notice: 'Joke was successfully added!'
    else
      render :new
    end
  end

  def update
    if @joke.update(joke_params)
      redirect_to root_path, notice: 'Joke was successfully updated.'
    else
      render :edit
    end
  end

  def destroy
    @joke.destroy
    redirect_to my_jokes_path, notice: 'Joke was successfully deleted.'
  end

  def edit
  end

  def about
  end

  private

  def joke_params
    params.require(:joke).permit(:joke, :name)
  end

  def set_joke
    @joke = Joke.find(params[:id])
  end

end

In rails console, when calling Author or Joke, neither are associated with each other.

I've tried so many different things and I can't get it to work. I've followed many answers from semi-related questions here and just through tutorials, but I suck. Please help, thanks! :)

REPO: https://github.com/joshzandman/random-joke

  • What do you mean by *In rails console, when calling Author or Joke, neither are associated with each other.*? – Pavan Jul 04 '17 at 04:02
  • For example: `2.4.0 :008 > Author => Author(id: integer, name: string, created_at: datetime, updated_at: datetime)` and if I do Author.jokes I get an error. –  Jul 04 '17 at 04:05
  • Whats the error? – Pavan Jul 04 '17 at 04:05
  • `NoMethodError: undefined method `jokes' for #` –  Jul 04 '17 at 04:06
  • Call it with variables like `author = Author.find(1)` and `author.jokes` – Pavan Jul 04 '17 at 04:07

1 Answers1

0

NoMethodError: undefined method jokes' for Class:0x007fbefa5c4160

You are doing it wrong by calling Author.jokes. You should use joins or includes

Author.joins(:jokes)

or

Author.includes(:jokes)

Also, your associations aren't right. You have has_many :jokes in Author which is right but you have has_one :author in Joke which isn't right. Perhaps you should have belongs_to :author. I recommend you to read associations

Pavan
  • 33,316
  • 7
  • 50
  • 76
  • I also needed to add `author_id` to the Joke model, but I still can't create a joke with an author using the `:name` attribute. –  Jul 04 '17 at 04:44
  • Sorry - error I get is: `ActiveModel::UnknownAttributeError: unknown attribute 'name' for Joke` –  Jul 04 '17 at 04:49
  • @JoshZandman How areyou doing it? It seems like you are adding it jokes name whereas jokes don't have name attribute. – Pavan Jul 04 '17 at 04:51
  • I thought I could use the attribute :name when creating a joke because they're associated? So confusing! I tried this: `joke = Joke.create :joke => 'something funny', :name => 'some name'` –  Jul 04 '17 at 04:53
  • @JoshZandman No! That's wrong. Instead add `author_id` to jokes model and map that joke to that particular author. But first add `author_id` in `jokes` table and change `has_one :author` to `belongs_to :author` in `Joke` model. – Pavan Jul 04 '17 at 04:56