ronatory ronatory - 2 months ago 16
Ruby Question

Variable passing to use path in partial

I'm learning Ruby on Rails by using this book.
I'm stuck on the second exercise from here.

My form partial

app/views/users/_form.html.erb
looks like this:

<%= form_for(@user, url: yield(:path)) do |f| %>
<%= render 'shared/error_messages', object: @user %>

<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>

<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>

<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>

<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation, class: 'form-control' %>

<%= f.submit yield(:button_text), class: "btn btn-primary" %>
<% end %>


My signup view
app/views/users/new.html.erb
with partial is this:

<% provide(:title, 'Sign up') %>
<% provide(:button_text, 'Create my account') %>
<% provide(:path, signup_path) %>
<h1>Sign Up</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= render 'form' %>
</div>
</div>


and my edit view
app/views/users/edit.html.erb
is this:

<% provide(:title, "Edit user") %>
<% provide(:button_text, "Save changes") %>
<% provide(:url, user_path) %>
<h1>Update your profile</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= render 'form' %>
<div class="gravatar_edit">
<%= gravatar_for @user %>
<a href="http://gravatar.com/emails" target="_blank" rel="noopener noreferrer">Change</a>
</div>
</div>
</div>


My problem is that I don't know which right path for the edit view I have to set with the provide method.

With signup_path it works fine for the signup view. What I tried for the edit view is:


  • user_path
    (currently in the code example)

  • edit_user_path

  • edit_user_path(@user)
    (to pass the user object)



Below the current routing error I got:

enter image description here

and below that the available routes related to user:

enter image description here

For example if I don't use provide for the edit view to provide an url, it works fine like here:

<%= form_for(@user) do |f| %>
<%= render 'shared/error_messages', object: @user %>

<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>

<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>

<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>

<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation, class: 'form-control' %>

<%= f.submit yield(:button_text), class: "btn btn-primary" %>
<% end %>


But the goal is to refactor the code using partials, so I need to provide an url for the signup view.

The
routes.rb
:

Rails.application.routes.draw do
get 'sessions/new'

get 'users/new'

root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
post '/signup', to: 'users#create'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :users
end

Answer

So in the end to pass the needed url as requirement from the second exercise here, it works with providing just the user_path. As I mentioned in my question I tried it already with user_path, but what I didn't saw was that I used in the form partial yield(:path), to embed the url, so when you look at my question for the signup view I provided the variable right with <% provide(:path, signup_path) %>, but in the edit view I used <% provide(:url, user_path) %>. So it's clear that I can't provide a right path from the edit view, even if I set the right one as you can see I described in my tries.

So for those who get also stuck on that exercise after trying on your own and after looking exactly if you assigned your variables right. This is my working solution:

The form partial app/views/users/_form.html.erb:

<%= form_for(@user, url: yield(:path)) do |f| %>
  <%= render 'shared/error_messages', object: @user %>

  <%= f.label :name %>
  <%= f.text_field :name, class: 'form-control' %>

  <%= f.label :email %>
  <%= f.email_field :email, class: 'form-control' %>

  <%= f.label :password %>
  <%= f.password_field :password, class: 'form-control' %>

  <%= f.label :password_confirmation %>
  <%= f.password_field :password_confirmation, class: 'form-control' %>

  <%= f.submit yield(:button_text), class: "btn btn-primary" %>
<% end %>

The signup view app/views/users/new.html.erb:

<% provide(:title, 'Sign up') %>
<% provide(:button_text, 'Create my account') %>
<% provide(:path, signup_path) %>

<h1>Sign Up</h1>
<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= render 'form' %>
  </div>
</div>

The edit view app/views/users/edit.html.erb:

<% provide(:title, "Edit user") %>
<% provide(:button_text, "Save changes") %>
<% provide(:path, user_path) %>

<h1>Update your profile</h1>
<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= render 'form' %>
    <div class="gravatar_edit">
      <%= gravatar_for @user %>
      <a href="http://gravatar.com/emails" target="_blank" rel="noopener noreferrer">Change</a>
    </div>
  </div>
</div>
Comments