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

[Rails :: Friendship UI] Tweak code so that you can create the friendship right on profiles/show.html.erb?

Hey all,

Nice to see this forum, great step up! Looking forward to sharing and learning here. My first post, input greatly appreciated.

Current situation, as coded by Jason in the tutorial "Building Social Features in Ruby on Rails :: Building The Friendship UI":

Say I am logged in as Bill. If I want to add Ted as a friend

  1. I have to go to his profile page (/ted).
  2. there, I have to click on the button "Add as a friend" (step 1). This will take me to a new page (/user_friendships/new?friend_id=ted).
  3. there I have to click on the "Yes, add friend" button to actually create the friendship (step 2).

Screenshot of current situation, with code and browser

I want the following situation:

  1. I have to go to his profile page (/ted)
  2. there, I have to click on the button "Add as a friend" (step 1). This will toggle a modal (overlaying prompt) (section about modals on twitter bootstrap)
  3. in this modal, I have to click an "Add as a friend button" to create the friendship (step 2).

So basically, I don't want there to be an intermediate page, just a modal. (Ideally, I want to also be able to create the friendship by just clicking on the first button --basically like 'liking' a status on Facebook-- but I guess let's take it one step at a time. )

Relevant code current situation:

view/profiles/show.html.erb

<div class="page-header"> 
  <%= link_to "Add this dude as a friend", new_user_friendship_path(friend_id: @user), class: 'btn' %></div>

views/user_friendships/new.html.erb

<% if @friend %>
  <h1><%= @friend.full_name%></h1>

  <p>Do you really want to friend <%= @friend.full_name %></p>

  <%= form_for @user_friendship, method: :post do |form| %>
    <div class="form form-actions">
        <%= form.hidden_field :friend_id, value: @friend.profile_name %>
        <%= submit_tag "Yes, add friend", class: 'btn btn-primary' %>
        <%= link_to "Cancel", profile_path(@friend), class: 'btn' %>
    </div>
  <% end %>
<% end %>

mockup code for modal on view/profiles/show.html.erb

<a data-toggle="modal" href="#add-friend-<%= @user.id %>" class="btn btn-mini" type="button">Add as a friend</a>

    <div id="add-friend-<%= @user.id %>" class="modal" style="display: none;">
        ????
    </div>

Obviously creating the modal is easy, but how do I move this form to the modal and let it create a user_friendship there, when we're currently in /view/profiles/show.html.erb ? Because form_for @user_friendship is not working there. Do I somehow need to include user_friendships in the ProfilesController?

11 Answers

I got it to work (in my own application) when I created the friendship controller in a slightly less involved way than in this tutorial (following railscast 163). Up way too late so I'm going to sleep now, but I'll try to post that method tomorrow.

Still very interested in how it would work with this approach though.

Jody Albritton
PLUS
Jody Albritton
Courses Plus Student 5,497 Points

You can take a look at my demo social app http://github.com/jodyalbritton/social-demo

It has like and follow buttons that work via ajax.

Demo here tranquil-ocean-7489.heroku.com

Thanks for helping Jody and Rik!

Firstly: wow, thanks Jody, feel like a kid in a candy store there after briefly checking out your demo. Can't wait to sit down in the weekend and check it out for real, lots to learn.

Secondly: so, following that railscast, I got it to work so that I can add the friend (or like/follow, whatever you wanna call it) right there on the profile page, by just clicking on the button. All you get is a flash notice, which is fine as far as I'm concerned. Code is in that video, but to give you an idea:

UserFriendshipsController

class UserFriendshipsController < ApplicationController

  def create
    @user_friendship = current_user.user_friendships.build(:friend_id => params[:friend_id])
    if @user_friendship.save
      flash[:notice] = "Added friend."
      redirect_to profile_path(@user_friendship.friend.username)
    else
      flash[:error] = "Unable to add friend."
      render :action => "new"
    end
  end

  def destroy
    @user_friendship = UserFriendship.find(params[:id])
    @user_friendship.destroy
    flash[:notice] = "User friendship was successfully destroyed."
    redirect_to root_url
  end
end

UserFriendship model

belongs_to :user
belongs_to :friend, :class_name => "User"

Profile show page

<%= link_to "Add #{@user.username} as a friend", user_friendships_path(:friend_id => @user), :method => :post, :class => 'btn btn-success' %>

Thirdly: thanks to y'all too Ryan, keep it up.

Jason Seifer
STAFF
Jason Seifer
Treehouse Guest Teacher

Great work, all! Also as a heads-up, we'll be covering something very similar in an upcoming stage :)

Nice! Thanks guys

Jody: I just cloned social-demo, would love to check it out locally and play with it. I made an account at the heroku address and it's looking great. But locally, I have 2 issues.

1) Upon starting up with 'rails s' and going to 'localhost:3000', I immediately got this error.

variable @fontAwesomeEotPath_iefix is undefined (in /Users/springest/Documents/Projects/social demo/social-demo/app/assets/stylesheets/bootstrap_and_overrides.css.less)

Google came up with this solution to the bug (easy enough!).

2) So with that fixed, social-demo loaded '/users/sign_in'. There, after navigating to '/users/sign_up' and submitting the form, I got the following error: screenshot. Any idea what's going on?

Full trace for the error:

        activemodel (3.2.8) lib/active_model/attribute_methods.rb:407:in `method_missing'
    activerecord (3.2.8) lib/active_record/attribute_methods.rb:149:in `method_missing'
    acts_as_follower (0.1.1) lib/acts_as_follower/follower.rb:89:in `method_missing'
    acts_as_follower (0.1.1) lib/acts_as_follower/followable.rb:54:in `method_missing'
    rolify (3.2.0) lib/rolify/role.rb:73:in `method_missing'
    friendly_id (4.0.9) lib/friendly_id/slugged.rb:253:in `should_generate_new_friendly_id?'
    friendly_id (4.0.9) lib/friendly_id/slugged.rb:273:in `set_slug'
    activesupport (3.2.8) lib/active_support/callbacks.rb:407:in `_run__3647306561749157587__validation__3108339719703615032__callbacks'
    activesupport (3.2.8) lib/active_support/callbacks.rb:405:in `__run_callback'
    activesupport (3.2.8) lib/active_support/callbacks.rb:385:in `_run_validation_callbacks'
    activesupport (3.2.8) lib/active_support/callbacks.rb:81:in `run_callbacks'
    activemodel (3.2.8) lib/active_model/validations/callbacks.rb:53:in `run_validations!'
    activemodel (3.2.8) lib/active_model/validations.rb:194:in `valid?'
    activerecord (3.2.8) lib/active_record/validations.rb:69:in `valid?'
    activerecord (3.2.8) lib/active_record/validations.rb:77:in `perform_validations'
    activerecord (3.2.8) lib/active_record/validations.rb:50:in `save'
    activerecord (3.2.8) lib/active_record/attribute_methods/dirty.rb:22:in `save'
    activerecord (3.2.8) lib/active_record/transactions.rb:241:in `block (2 levels) in save'
    activerecord (3.2.8) lib/active_record/transactions.rb:295:in `block in with_transaction_returning_status'
    activerecord (3.2.8) lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
    activerecord (3.2.8) lib/active_record/transactions.rb:208:in `transaction'
    activerecord (3.2.8) lib/active_record/transactions.rb:293:in `with_transaction_returning_status'
    activerecord (3.2.8) lib/active_record/transactions.rb:241:in `block in save'
    activerecord (3.2.8) lib/active_record/transactions.rb:252:in `rollback_active_record_state!'
    activerecord (3.2.8) lib/active_record/transactions.rb:240:in `save'
    devise (2.1.2) app/controllers/devise/registrations_controller.rb:15:in `create'
    actionpack (3.2.8) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
    actionpack (3.2.8) lib/abstract_controller/base.rb:167:in `process_action'
    actionpack (3.2.8) lib/action_controller/metal/rendering.rb:10:in `process_action'
    actionpack (3.2.8) lib/abstract_controller/callbacks.rb:18:in `block in process_action'
    activesupport (3.2.8) lib/active_support/callbacks.rb:447:in `_run__1395863590985179656__process_action__1820175588625991196__callbacks'
    activesupport (3.2.8) lib/active_support/callbacks.rb:405:in `__run_callback'
    activesupport (3.2.8) lib/active_support/callbacks.rb:385:in `_run_process_action_callbacks'
    activesupport (3.2.8) lib/active_support/callbacks.rb:81:in `run_callbacks'
    actionpack (3.2.8) lib/abstract_controller/callbacks.rb:17:in `process_action'
    actionpack (3.2.8) lib/action_controller/metal/rescue.rb:29:in `process_action'
    actionpack (3.2.8) lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'
    activesupport (3.2.8) lib/active_support/notifications.rb:123:in `block in instrument'
    activesupport (3.2.8) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
    activesupport (3.2.8) lib/active_support/notifications.rb:123:in `instrument'
    actionpack (3.2.8) lib/action_controller/metal/instrumentation.rb:29:in `process_action'
    actionpack (3.2.8) lib/action_controller/metal/params_wrapper.rb:207:in `process_action'
    activerecord (3.2.8) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
    actionpack (3.2.8) lib/abstract_controller/base.rb:121:in `process'
    actionpack (3.2.8) lib/abstract_controller/rendering.rb:45:in `process'
    actionpack (3.2.8) lib/action_controller/metal.rb:203:in `dispatch'
    actionpack (3.2.8) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
    actionpack (3.2.8) lib/action_controller/metal.rb:246:in `block in action'
    actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:73:in `call'
    actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:73:in `dispatch'
    actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:36:in `call'
    actionpack (3.2.8) lib/action_dispatch/routing/mapper.rb:42:in `call'
    journey (1.0.4) lib/journey/router.rb:68:in `block in call'
    journey (1.0.4) lib/journey/router.rb:56:in `each'
    journey (1.0.4) lib/journey/router.rb:56:in `call'
    actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:600:in `call'
    bullet (4.2.0) lib/bullet/rack.rb:8:in `call'
    /Users/springest/.rvm/gems/ruby-1.9.3-p125/bundler/gems/client_side_validations-7145c84c3737/lib/client_side_validations/middleware.rb:21:in `call'
    warden (1.2.1) lib/warden/manager.rb:35:in `block in call'
    warden (1.2.1) lib/warden/manager.rb:34:in `catch'
    warden (1.2.1) lib/warden/manager.rb:34:in `call'
    actionpack (3.2.8) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
    rack (1.4.1) lib/rack/etag.rb:23:in `call'
    rack (1.4.1) lib/rack/conditionalget.rb:35:in `call'
    actionpack (3.2.8) lib/action_dispatch/middleware/head.rb:14:in `call'
    remotipart (1.0.2) lib/remotipart/middleware.rb:30:in `call'
    actionpack (3.2.8) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
    actionpack (3.2.8) lib/action_dispatch/middleware/flash.rb:242:in `call'
    rack (1.4.1) lib/rack/session/abstract/id.rb:205:in `context'
    rack (1.4.1) lib/rack/session/abstract/id.rb:200:in `call'
    actionpack (3.2.8) lib/action_dispatch/middleware/cookies.rb:339:in `call'
    activerecord (3.2.8) lib/active_record/query_cache.rb:64:in `call'
    activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_pool.rb:473:in `call'
    actionpack (3.2.8) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
    activesupport (3.2.8) lib/active_support/callbacks.rb:405:in `_run__2352364880503786316__call__3108339719703615032__callbacks'
    activesupport (3.2.8) lib/active_support/callbacks.rb:405:in `__run_callback'
    activesupport (3.2.8) lib/active_support/callbacks.rb:385:in `_run_call_callbacks'
    activesupport (3.2.8) lib/active_support/callbacks.rb:81:in `run_callbacks'
    actionpack (3.2.8) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
    actionpack (3.2.8) lib/action_dispatch/middleware/reloader.rb:65:in `call'
    actionpack (3.2.8) lib/action_dispatch/middleware/remote_ip.rb:31:in `call'
    actionpack (3.2.8) lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call'
    actionpack (3.2.8) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
    railties (3.2.8) lib/rails/rack/logger.rb:26:in `call_app'
    railties (3.2.8) lib/rails/rack/logger.rb:16:in `call'
    actionpack (3.2.8) lib/action_dispatch/middleware/request_id.rb:22:in `call'
    rack (1.4.1) lib/rack/methodoverride.rb:21:in `call'
    rack (1.4.1) lib/rack/runtime.rb:17:in `call'
    activesupport (3.2.8) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
    rack (1.4.1) lib/rack/lock.rb:15:in `call'
    actionpack (3.2.8) lib/action_dispatch/middleware/static.rb:62:in `call'
    railties (3.2.8) lib/rails/engine.rb:479:in `call'
    railties (3.2.8) lib/rails/application.rb:223:in `call'
    rack (1.4.1) lib/rack/content_length.rb:14:in `call'
    railties (3.2.8) lib/rails/rack/log_tailer.rb:17:in `call'
    thin (1.5.0) lib/thin/connection.rb:81:in `block in pre_process'
    thin (1.5.0) lib/thin/connection.rb:79:in `catch'
    thin (1.5.0) lib/thin/connection.rb:79:in `pre_process'
    thin (1.5.0) lib/thin/connection.rb:54:in `process'
    thin (1.5.0) lib/thin/connection.rb:39:in `receive_data'
    eventmachine (1.0.0) lib/eventmachine.rb:187:in `run_machine'
    eventmachine (1.0.0) lib/eventmachine.rb:187:in `run'
    thin (1.5.0) lib/thin/backends/base.rb:63:in `start'
    thin (1.5.0) lib/thin/server.rb:159:in `start'
    rack (1.4.1) lib/rack/handler/thin.rb:13:in `run'
    rack (1.4.1) lib/rack/server.rb:265:in `start'
    railties (3.2.8) lib/rails/commands/server.rb:70:in `start'
    railties (3.2.8) lib/rails/commands.rb:55:in `block in <top (required)>'
    railties (3.2.8) lib/rails/commands.rb:50:in `tap'
    railties (3.2.8) lib/rails/commands.rb:50:in `<top (required)>'
    script/rails:6:in `require'
    script/rails:6:in `<main>'

(Btw, omg, this was preceeded by a grueling couple hours trying to get postgresql to work :D In the end it turned out I had in database.yml I had to use 'postgres' as username & my Mac user's password as the password. Aso added the line 'port: 5432' but I'm not sure if that was necessary. If anyone has issues, drop 'em here, I might've had the same one somewhere along the way.)

Jody Albritton
PLUS
Jody Albritton
Courses Plus Student 5,497 Points

Nevermind, it was a bug.

line #5

app/models/user.rb should be :

 friendly_id :username, use: :slugged

Yes. To be sure, I just ran 'rake db:reset', and I still get the same error.

Jody Albritton
PLUS
Jody Albritton
Courses Plus Student 5,497 Points

I posted the fix above, I have also fixed the source if you want to just do a pull.

Oh man, awesome. Thanks a lot!