Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby

Showing statuses on profile page

I successfully added "statuses" (but mine is called "reviews") to appear on my profile page. However I would like to have something else appear as well. I am copying the code exactly and just adding another snippet of code but it's not working. Any help would be appreciated.Here is my code (rails 4):class ProfilesController < ApplicationController

def show @user = User.find_by_name(params[:id]) if @user @reviews = @user.reviews.all @logs = @user.logs.all render action: :show else render file: 'public/404', status: 404, formats: [html] end end end

The logs are not appearing.

18 Answers

So you have a model called "log"?

Make sure in the model (log.rb file) that you have

belongs_to :user

And in the user.rb file, you have:

has_many :logs

Those associations allow you to use the shortcuts: @user.logs

Hi Brandon, yup I have those includes. Which is why I don't understand why I can't call the @logs = @user.logs.all option.

Do you have any logs in the database? Also, make sure @user is defined and all of the logs have a user_id field in the database table.

what do you mean by logs in the database? Like if I posted some? If that's what you mean then yes, and I do believe its defined in the database (migrate) folder.

I have it defined under the name add_user_id_to_logs.rb

class AddUserIdToLogs < ActiveRecord::Migration def change add_column :logs, :user_id, :integer add_index :logs, :user_id end end

In your terminal, type

rails console 

to open up the console. Then type

Log.all

That will display all the rows in the database table. If there isn't data in the table, then it won't show in your view. If there is, then I'd need to see all your code for log.rb, logs_controller.rb and user.rb to try and diagnose. And also probably the profile_controller.rb if that is where you are trying to show your logs.

hi brandon, did the console command and there is data in the table.

Here is my code for log.rb:

class Log < ActiveRecord::Base belongs_to :user

 has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }

 validates :image, :presence => true
 validates :description, :presence => true

end

Logs_controller.rb:

class LogsController < ApplicationController before_action :set_log, only: [:show, :edit, :update, :destroy] before_action :correct_user, only: [:edit, :update, :destroy] before_action :authenticate_user!, except: [:index, :show]

def index @logs = Log.all.order('created_at DESC').paginate(:page => params[:page], :per_page => 2) end

def show end

def new @log = current_user.logs.build end

def edit end

def create @log = current_user.logs.build(log_params) if @log.save redirect_to @log, notice: 'Log was successfully created.' else render action: 'new' end end

def update if @log.update(log_params) redirect_to @log, notice: 'Log was successfully updated.' else render action: 'edit' end end

def destroy @log.destroy redirect_to logs_url end end

private # Use callbacks to share common setup or constraints between actions. def set_log @log = Log.find(params[:id]) end

def correct_user
  @log = current_user.logs.find_by(id: params[:id])
  redirect_to logs_path, notice: "Not authorized to edit this log!" if @log.nil?
end

# Never trust parameters from the scary internet, only allow the white list through.
def log_params
  params.require(:log).permit(:description, :image)
end

user.rb:

class User < ActiveRecord::Base # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable

has_many :logs

has_many :reviews

has_attached_file :avatar, styles: {

large: "800x800", medium: "300x300", small: "260x260", thumb: "80x80#"

}

validates :name, :presence => true

end

Profiles_controller.rb:

class ProfilesController < ApplicationController

def show @user = User.find_by_name(params[:id]) if @user @reviews = @user.reviews.all render action: :show else render file: 'public/404', status: 404, formats: [html] end end end

Where are you trying to show the logs? Are you trying to show them on the profile page? I'm getting all your stuff confused. You seem to have:

@reviews = @user.reviews
@logs = @user.logs

Where do you want to the @logs to show up? If on the profile page, it has to be defined in the profile controller.

actually I figured out how to get the logs to show up on the profile page, not I just don't know how to get it on the index page. I am rendering it but it keeps showing a nomethoderror and when i add the method in the controller it still doesn t work

If you paste the exact error you're getting and the code in both the view and controller I can try to help diagnose. I know how frustrating it can be, I was in your shoes about 6 months ago.

thanks brandon

error: NoMethodError in Reviews#index undefined method `attachment' for nil:NilClass

reviews/index.html.erb file:

<div id='reviews' class='transitions-enabled'> <% @reviews.each do |review| %>

<div class='box panel panel-default'>

<div class='panel-body'> <p><%= review.description %></p> <p><strong><%= review.user.name if review.user %></strong></p> <%= link_to Time.now.strftime("%m/%d/%Y"), review %> <% if review.user == current_user %>

<div class='actions'> <%= link_to edit_review_path(review) do %> <span class="glyphicon glyphicon-edit"></span> Edit <% end %> <%= link_to review, method: :delete, data: { confirm: 'Are you sure?' } do %> <span class="glyphicon glyphicon-trash"></span>Delete <% end %> </div> <% end %> </div> </div> <% end %> </div>

<%= render template:"logs/show" %>

<%= link_to new_review_path do %> <span class="glyphicon glyphicon-pencil"></span>New Review <% end %>

reviews_controller.rb:

class ReviewsController < ApplicationController before_action :set_review, only: [:show, :edit, :update, :destroy] before_action :correct_user, only: [:edit, :update, :destroy] before_action :authenticate_user!, except: [:index, :show]

def index @reviews = Review.all.order('created_at DESC').paginate(:page => params[:page], :per_page => 2) end

def show end

def new @review = current_user.reviews.build end

def edit end

def create @review = current_user.reviews.build(review_params) if @review.save redirect_to @review, notice: 'review was successfully created.' else render action: 'new' end end

def update if @review.update(review_params) redirect_to @review, notice: 'Review was successfully updated.' else render action: 'edit' end end

def destroy @review.destroy redirect_to reviews_url end end

private # Use callbacks to share common setup or constraints between actions. def set_review @review = Review.find(params[:id]) end

def correct_user @review = current_user.reviews.find_by(id: params[:id]) redirect_to reviews_path, notice: "Not authorized to edit this review!" if @review.nil? end

# Never trust parameters from the scary internet, only allow the white list through.

def review_params params.require(:review,).permit(:description, :attachment) end

So this error is telling me that there is an error with your attachment.

 error: NoMethodError in Reviews#index undefined method `attachment' for nil:NilClass

I don't see the attachment in the code though, so i'm assuming it is here:

<%= render template:"logs/show" %>

So, i'm not sure why you would be rendering the show template for logs. That implies that there is 1 specific log you want to show. If that is the case, then you haven't defined that log in the index action of the resume controller. And I'm pretty sure that's what it is because you have an attachment on logs.

So, two things you could do. remove that line (to check that everything else works). Then, in your index action of the resume controller, you need and instance variable for "@log".

Now, this could only work if each resume has only 1 log. If this is the case, then you can just call:

@log = @resume.log

Although, when I looked above at your log.rb file, I didn't see any association between logs and resumes.

If the each resume can have many logs, then the associations would be:

resume.rb has_many :logs
log.rb belongs_to :resume

Then in the index action of the resume controller, you can say @logs = @resume.logs and then you don't want to render the show action, and just run an each loop to loop through the @logs

@logs.each do |log|
    #stuff here
end

Hope that makes sense! I think this should work from the information given to me.

Hi Brandon, thanks so much for your response. I think we're getting closer. I'm not trying to only show one log on the review index. I am trying to show all of them.

when I place the code

@logs = @Logs.all

in the reviews controller like so:

def index @reviews = Review.all.order('created_at DESC').paginate(:page => params[:page], :per_page => 2) @log = Log.all end

I get an uninitialized constant error.

if I remove the method ( @log = Log.all) and add this to my review/index.html.erb page: <%= render template:"logs/index" %>

I get an this error: undefined method `each' for nil:NilClass

so it's weird because when I try to define the logs method in the reviews controller I get an error, and when I don't define it I still get an error...there's no winning! lol

There are no associations between reviews and logs, I just want them to show up on the same page.

Ok. So what you need. Remove the render show on reviews index. This is just going to cause chaos. We will make our own code to view them all.

Then in the review index action, we need to define @reviews and @logs. @reviews is already defined, but we can't say @log (because that is only 1). So for the reviews controller, we have:

def index
    @reviews = Review.all
    @logs = Log.all
end

Now, in the view, we should do:

<% @logs.each do |log| %>
    <%= log.name %>
    #or whatever you want to spit out here, I don't know the columns in the log db you want to show
    <% link_to log.name, log_path(log) %>
    #this will link to the show action of log to show a specific log
<% end %>

Hope this makes sense/helps. I think I understand what you are trying to do now. Let me know if that works now.

Ok I'll try it, can I harass you with one more quick question? I slightly messed up (more then slight) and I'm trying to download my old code from github. How do i do that? When I download the zip file and try to run it I get an error.

it get this error: Could not find pg-0.17.0 in any of the sources Run bundle install to install missing gems.

and this error: Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension

So I'm pretty sure pg is the postgreSQL gem. So there is some error there.

I noticed you're using Rails 4, and i'm still on Rails 3.2.12 because that's what the treehouse videos are in. So I don't know if that could be causing some problems, since not all gems will necessarily work right away, and some may not work at all if they aren't being maintained.

At this point I don't know if I can be of much more help, it seems like a lot of errors. One thing i've learned is to try one thing at a time, make sure it functions, then slowly add the features I want. I even walk away from my code for a few days while still thinking about it and can think of new ways to attack the problem.

Good luck! If you get any more errors, I can try to help, but can't promise anything. You might want to try posting on stack overflow as well.