Ruby on Rails / Devise - 将用户编辑页面拆分为2页

时间:2015-12-09 16:43:31

标签: ruby-on-rails ruby devise

我尝试将用户编辑页面(app / views / devise / registrations / edit.html.erb)拆分为2页以获得更好的用户界面,例如:

var_name = "HelloWorld"
f = File.open("file.ex", "r").read
    # puts f.class => String
puts f
    #  #{var_name} is print and no HelloWorld

我对Rails相当陌生,做过Michael Hartl的教程并阅读了一些我得到的东西,只是构建我的第一个应用程序,即使我有一些PHP的经验

这是我试图在2中拆分的视图,它是由Devise gem提供的视图(app / views / devise / registrations / edit.html.erb)

/settings 
/settings/profile

它使用自定义RegistrationsController(app / controllers / registrations_controller.rb)

<h2>Login Details</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
  <%= devise_error_messages! %>

  <%# sensitive info %>
  <%= f.label :email %><br />
  <%= f.email_field :email, autofocus: true %>
  ....
  <%= f.label :current_password %> <i>(to confirm changes)</i><br />
  <%= f.password_field :current_password, autocomplete: "off" %>

  <h2>Profile Details</h2>

  <%# non-sensitive info %>
  <%= f.label :name %><br />
  <%= f.text_field :name %>

  <%= f.submit "Update" %>
<% end %>

此外,可以通过以下途径访问此视图:

class RegistrationsController < Devise::RegistrationsController
  def update
    ....
  end
end

我的主要问题是,如何将此页面拆分为2:

  • /包含登录详细信息的设置
  • /包含个人资料详情的设置/个人资料

并且两者都由同一个控制器或相同的动作处理

我是否需要创建新的控制器/路径/视图,例如:

  • controller:SettingsProfile
  • 路线:获取&#39;设置/个人资料&#39; =&GT; &#39;#settings_profile新&#39;
  • view:app / views / settings_profile / new.html.erb

如果是这样,我如何通过视图&#34;资源&#34;信息,或任何事实的信息:

edit_user GET      /users/:id/edit(.:format)              users#edit

此时情况非常模糊,请耐心等待。

3 个答案:

答案 0 :(得分:1)

正如您所建议的,一种方法是创建一个新的控制器,路由和视图来处理这个问题。

我可能会创建一个UserProfilesController控制器,其中包含两项操作:UserProfilesController#showUserProfilesController#edit

然后如你所说,路线,例如

get 'user_profiles/:id' => 'user_profiles#show'
get 'user_profiles/:id/edit' => 'user_profiles#edit'

在Devise的说法中,resource指的是用户。因此,上面传递的:id当然必须是User id。如果您不想这样做,您可以随时假设您的意思是current_user,在这种情况下您可以跳过路由中的:id并通过{{在控制器中检索它1}}。

最后,您只需从“设计”视图中拆分配置文件详细信息,然后在current_user.id下创建一些,并为app/views/user_profiles/new.html.erb创建类似设置。请记住从Devise视图中删除配置文件位,我认为您已经开始了。

附录

@AmrNoman提出了一个很好的建议:更新方法。如果您使用我的解决方案,则需要在edit.html.erb文件中添加其他操作UserProfilesController#update和新路线:

routes.rb

此外,如果您打算稍后重构put 'user_profiles/:id/update' => 'user_profiles#update' 以删除配置文件详细信息并在单独的模型中处理它们,将上述代码中对User的引用替换为{{}可能是谨慎的做法。 1}}。通过这种方式,如果您在某个时刻创建了一个名为:id的模型,那么:user_id不是UserProfile而是:id外键会更清楚。这样,您就可以使用UserProfile#id直接引用UserProfile#user_id,而不会影响应用中的任何API消费者。

这可能有点矫枉过正,但我​​认为这是一种很好的做法。

答案 1 :(得分:1)

Chris Cameron的回答是正确的,但我认为这更接近你想要的:

首先在 routes.rb

中创建路线
  # this gets the edit page for login details
  get "settings" => "user_profiles#edit_credentials", as: "edit_credentials"

  # this gets the edit page for other profile info
  get "settings/edit" => "user_profiles#edit_profile", as: "edit_profile"

  # update method shared by both forms 
  # (you can create another one to handle both forms separately if you want)
  put "settings" => "user_profiles#update"

然后您的控制器 user_profiles_controller.rb

class UserProfilesController < ApplicationController
  # fill the methods as you need, you can always get the user using current_user

  def edit_credentials
  end

  def edit_profile
  end

  def update
  end
end

最后是您的观看次数,首先是 views / user_profiles / edit_credentials.erb.html ,此处显示登录详细信息表单:

<%= form_for(current_user, url: settings_path) do |f| %>
<% end %>

然后在 views / user_profiles / edit_profile.erb.html 中进行相同的操作,只需更改您的表单内容:

<%= form_for(current_user, url: settings_path) do |f| %>
<% end %>

可能存在一些错误,但希望这会让您朝着正确的方向前进(同时确保处理身份验证和授权)。

答案 2 :(得分:1)

您不需要单独的控制器,尤其是因为您已经扩展了默认的Devise RegistrationsController,它已经可以正常更新用户属性。

编辑:如果这些不是扩展的用户属性,profile是自己的对象,有自己的逻辑和行为,那么 < / em>考虑创建它自己的控制器,以管理该对象的CRUD。

如果您正在使用设计的用户/编辑页面作为第一部分,那么您只需在自定义控制器中添加profile操作,并创建一个视图文件它

# this is all that's in the edit action from Devise
def edit
  render :edit
end

# add this to your custom RegistrationsController
def profile
  render :profile
end

然后,您可以摆弄路线(请参阅thisthis),直到他们将您要使用的网址路由到正确的控制器:

# you probably have this, which covers your current user/edit route
devise_for :users

# but you can add this to extend these routes
devise_scope :user do
  # will route /profile to the profile action on User::RegistrationsController
  get :profile, to: 'users/registrations'

  # or if you want more control over the specifics
  get 'users/settings/profile', to: 'users/registrations#profile', as: :user_profile
end

要让您的第二个视图/表单从另一个非设计控制器更新用户属性,您可以使用form_for current_user, { url: user_registration_path }

如果您确实想使用资源,则必须将其添加到注册控制器的顶部,以便在您的个人资料操作中定义资源:

prepend_before_filter :authenticate_scope!, only: [:edit, :profile, :update, :destroy]

请查看devise's documentation around strong parameters,了解如何确保您要添加到用户的任何其他属性都是由您的自定义RegistrationsController列出的白色。