变量传递以在部分中使用路径

Variable passing to use path in partial

我正在 Rails 上使用这个 book 学习 Ruby。 我卡在了 here.

的第二个练习上

我的表格部分 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 %>

我的部分注册视图 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>

我的编辑视图 app/views/users/edit.html.erb 是这样的:

<% 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>

我的问题是我不知道 edit view 的正确路径我必须使用 provide 方法设置。

使用 signup_path 它可以很好地用于注册视图。我为编辑视图尝试的是:

下面我得到的当前路由错误:

及以下与用户相关的可用路线:

例如,如果我不使用 provide for the edit view 来提供 url,它可以正常工作,如下所示:

<%= 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 %>

但目标是使用局部重构代码,因此我需要为注册视图提供 url。

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

您不必声明路径。如果你使用 resources :users。您的应用程序将知道如何设置路径。如果你声明:

@user = User.new

路径将是:

new_user_path

但是如果你声明:

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

路径将是:

user_path(id)

http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Resources.html

所以最后要通过第二个练习 here 的要求传递所需的 url,它只提供 user_path。正如我在问题中提到的,我已经用 user_path 尝试过,但我没有看到的是我以部分 yield(:path) 的形式使用来嵌入 url,所以当你查看我的注册视图问题,我使用 <% provide(:path, signup_path) %> 提供了变量权利,但在编辑视图中我使用了 <% provide(:url, user_path) %>。所以很明显我无法从编辑视图中提供正确的路径,即使我设置了正确的路径,正如您在我的尝试中所描述的那样。

因此,对于那些在自己尝试并仔细查看变量分配是否正确之后也卡在该练习中的人。这是我的工作解决方案:

表格部分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 %>

注册视图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>

编辑视图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>