Melbourne2991
Melbourne2991

Reputation: 11797

Setting user_id for post creation in Rails

I am having trouble setting the user_id on the creation of a post

def create

  @post = Post.new(post_params)
  @post.user_id = session[:id]

  respond_to do |format|
    if @post.save
      format.html { redirect_to @post, notice: 'Post was successfully created.' }
      format.json { render action: 'show', status: :created, location: @post }
    else
      format.html { render action: 'new' }
      format.json { render json: @post.errors, status: :unprocessable_entity }
    end
  end
end

The error I get is specifically undefined method 'username' for nil:NilClass when redirected to the show action. A look at the database shows that no user_id is set.

I also tried passing the user_id as a hidden field. but this did not work either (a look at the logs showed the hidden field wasn't even being passed for some reason).

Would appreciate a point in the right direction,

Thank you !

EDIT: as requested here is the show controller

def show
    @post = Post.find(params[:id])

    @original_id = params[:original_id]

    @comment = Comment.new
end

<%= form_for [:admin, @post] do |f| %>
  <% if @post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
      <% @post.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

Below is the form

  <div class="field">
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :content %><br>
    <%= f.text_area :content %>
  </div>
  <div class="field">
    <%= f.label :category %><br>
    <%= f.text_field :category %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Routes:

root 'posts#index'

  resources :posts do
    resources :comments, shallow: true
  end

  resources :users, only: [:create]

  #Posts
  get "/meta", to: "posts#meta"

  #User Routes
  get "/signup", to: "users#new"
  get "/success", to: "users#index"

  #login Routes
  get "/login", to: "sessions#login"
  post "/sessions/login_attempt", to: "sessions#login_attempt"

  #session routes
  get "/sessions/home", to: "sessions#home"
  get "/sessions/logout", to: "sessions#logout"

  #admin routes
  #resources :posts, module: 'admin', except: [:show, :index]
  namespace :admin do 
    root 'posts#new'
    resources :posts, except: [:show, :index]
  end

Upvotes: 0

Views: 4087

Answers (3)

Melbourne2991
Melbourne2991

Reputation: 11797

I feel like an idiot now but the issue was I was using session[:id] as opposed to session[:user_id]

Set in my sessions controller

def login_attempt
authorized_user = RegisteredUser.authenticate(params[:username_or_email],params[:login_password])
    if authorized_user
      session[:user_id] = authorized_user.id
      flash[:notice] = "Wow Welcome again, you logged in as #{authorized_user.username}"
      redirect_to(:action => 'index', :controller => "users")
    else
      flash[:notice] = "Invalid Username or Password"
      flash[:color]= "invalid"
      render "login"    
    end   
end

Upvotes: 0

coletrain
coletrain

Reputation: 2849

Inside of your create method add

@post = Post.build(params[:post])
@post.user_id = current_user.id

This will grab the current user id for the given post.

Upvotes: 3

ezis
ezis

Reputation: 311

If you have a has_many relationship between posts and users, why not do something like this:

@user = User.find(params[:id])
@post = @user.posts.new(params[:post])

The params might be different but this is the 'more ruby' way do do things. It explicitly notes the relationships between the two models. The above code should be in the #new action and then you would save it within the create action.

Upvotes: 0

Related Questions