0

I have a User model that has many galleries and categories(both separate models that belong_to :user). I would like to create a default category named "Everything" and a default gallery entitled "Everything".

I am adapting Mike Hartl's tutorial for my app, specifically the User creation and activation part. So, after a user is created using this code:

User.rb

def create
    @user = User.new(user_params)
    if @user.save
        @user.send_activation_email
        flash[:info] = 'Please check your email to activate your account.'
        redirect_to root_url
    else
        render 'new'
    end
end

An activation email is sent to the User and if they click on the link it will activate their account. At the point of activation, so the activated column switches from false to true, I would like the "Everything" gallery and category to be created. In my mind that is the most logical place for this to happen because it is likely to only be triggered once. That way I dont' have to worry about an "Everything" category and gallery trying to be created everytime someone logs on to their account.

The way I am trying to create these is by inserting the following code immediately after the account is activated:

user.categories = user.categories.build(name: 'Everything')

So it looks like, this:

account_activations_controller.rb
class AccountActivationsController < ApplicationController
    def edit
        user = User.find_by(email: params[:email])
        if user && !user.activated? && user.authenticated?(:activation, params[:id])
            user.activate
            user.categories = user.categories.build(name: 'Everything')
            log_in user
            flash[:success] = 'Account activated!'
            redirect_to user

        else
            flash[:danger] = 'Invalid activation link'
            redirect_to root_url
        end
    end
end

My problem is that while the User is created, the "Everything" category is not and I get the following error, which I can't reconcile:

NoMethodError at /account_activations/0hbg0T33tjQlleiwKqvUDg/edit
undefined method `each' for #<Category:0x00000004f95b60>

I don't know where 'each' would be called in this process.

Though I mentioned creating a gallery and category and user activation, the above code only address category. It seems to me that if I can get a category to work I should be able to get the gallery to work using a similar solution. This is what my create action looks like for category:

  def new
    @category = current_user.categories.build
  end

  def create
    @category = current_user.categories.create(category_params)
    if @category.save!
      respond_to do |format|
        format.html
        format.js
      end

    end
  end

I have a couple questions related to my issue:

  1. The first is the the most obvious, why am I getting the nomethod error, there doesn't appear to be an 'each' method associated with categories?

  2. Am I approaching this issue correctly? Should I trigger the creation of my default category and gallery from somewhere else in the code? I've read a bit about a .change? that I tried to use on the activated column on User, but I couln't figure out how to use it.

Any help you can offer is greatly appreciated.

Lenocam
  • 331
  • 2
  • 17

2 Answers2

1

You are trying to assign the result of user.categories.build(name: 'Everything') to user.categories. user.categories.build(name: 'Everything') creates the new record on it's own. You do not need to further assign it to user.categories. Trying to do so is causing Rails to iterate on the result of user.categories.build(name: 'Everything'), which is a single Category, not a collection.

So the solution to your question 1 is to replace:

user.categories = user.categories.build(name: 'Everything')

with:

user.categories.build(name: 'Everything')

The answer to question 2 depends on how many different places and/or ways a user can be activated. If the controller action for activating is the only place, your solution is probably fine. But if you ever want to activate a user another way (from the console, for example), you would probably be better off using a an ActiveRecord callback on User, such as :after_save and checking for user.activated_changed? && user.activated?, then generating the generic category and gallery there.

In either case, you may want to consider checking that the generic category and gallery don't already exist for the user (in case they were once activated and then deactivated), before creating them.

Bill Doughty
  • 2,250
  • 14
  • 20
0

I figured out what I was doing wrong. I was trying to create categories/an array instead of a category/a single object. I turned this:

user.categories = user.categories.build(name: 'Everything')

to this:

user.categories << user.categories.create(name: 'Everything')
Lenocam
  • 331
  • 2
  • 17