Rails 3 & Devise: Keeping track of who-owns-profile for user posts

826 views Asked by At

My app has a user model and a post model, where user has_many posts and posts belong_to users. Posts are displayed on a user's profile page. I'd like for any user to be able to post on his own, or any other user's profile page. However, the problem I'm having is that while I know who is posting (current_user), I don't know whose profile current_user is on. I need to know this in order to assign the new post to that user's posts. How do I extract user id information from the profile currently being viewed, so I know where to assign the new post?

My micropost controller looks like:

class MicropostsController < ApplicationController
  before_filter :authenticate_user!

  def create
   @user_of_page = User.find_by_name(params[:id]) 
   @micropost = @user_of_page.microposts.build(params[:micropost])
    if @micropost.save
      flash[:success] = "Micropost created!"
      redirect_to :back
    else
      redirect_to about_path
    end
  end

  def destroy
  end
end

But I'm getting a NoMethodError: undefined method `microposts' for nil:NilClass. I assume this is because I'm making some mistake with the creation of the user_of_page variable, but I don't know what that is!

SOLUTION

Thanks Sam. I took your advice and ended up doing it like this:

  1. I added a column to my Micropost table called belongs_to_id.

  2. I then passed the id of the user whose profile is being shown from the user show view to the micropost controller using a hidden field in the micropost form, like so:

       <%= form_for @micropost do |f| %>
       <%= render 'shared/error_messages', :object => f.object %>
    
       <div class="field">
          <%= f.label :content, "Why that mood?" %>
          <%= f.text_area :content %>
       </div>
    
       <div class="field">
          <%= f.hidden_field :author, :value => current_user.name %>
          <%= f.hidden_field :belongs_to_id, :value => @user.id %>
      <%= f.hidden_field :agree, :value => "0" %>
      <%= f.hidden_field :disagree, :value => "0" %>
      <%= f.hidden_field :amused, :value => "0" %>
       </div>
    
       <div class="actions">
          <%= f.submit "Submit" %>
       </div>
     <% end %>
    
  3. I then used this id value to search for the user to assign the post to, in the micropost controller, like so:

    class MicropostsController < ApplicationController
      before_filter :authenticate_user!
    
      def create
       @user_of_page = User.find(params[:micropost][:belongs_to_id]) 
       @micropost = @user_of_page.microposts.build(params[:micropost])
        if @micropost.save
          flash[:success] = "Micropost created!"
          redirect_to :back
        else
           redirect_to about_path
        end
      end
    
      def destroy
      end
    end
    

Magic! Thanks again, you helped me to see it in the right way.

1

There are 1 answers

0
Syed Aslam On BEST ANSWER

I would do it like this:

class profiles_controller < AC
  ...
  def show
    @profile = User.find(params[:id]).profile || current_user.profile
    @post = Post.new       
  end
  ..
end

/profiles/show.html.erb
... 
Name: <%= @profile.full_name %> 
...
<%= form_for @post do |f| %>
  <%= hidden_field_tag @profile.user %>
  ...
<% end %>

class microposts_controller < AC
  def create
    profile_user = User.find(params[:user_id]) # Owner of the profile current_user is on
    ..
  end
end

Not tested. Hope this helps.