从另一个控制器更新模型而不传递ID?

时间:2013-06-03 16:35:08

标签: ruby-on-rails ruby-on-rails-3 refactoring logic

我试图更新我的个人资料模型真的是welcome_controller。 这样做的原因是我有一些步骤作为用户构建他的初始个人资料的欢迎wizzard。

我无法正确使用路由,因为我没有提供ID。

  • welcome#edit /:step加载正确的步骤
  • welcome#update应更新配置文件属性并保存其所在的步骤(总共3个步骤)

的routes.rb

  match "/welcome/:step" => "welcome#edit"
  match "/welcome" => "welcome#edit"
  resources :welcome

welcome_controller更新和修改操作:

    def edit
    # form updates post to edit since
    # profile is non existant yet

    params[:step] = "photos" unless params[:step]
    @photos   = Photo.where(:attachable_id => current_user.id)
    @profile  = Profile.where(:user_id => current_user.id).first
    @photo    = Photo.new


    if ["photos", "basics", "details"].member?(params[:step])
      render :template => "/profiles/edit/edit_#{ params[:step]}", :layout => "welcome"
    else
      render :action => "/profiles/edit_photos"
    end

    end

  # update profile attributes then update the correct step
  def update

    raise('welcome update called')
    @profile = Profile.where(:user_id => current_user.id).first
    @profile.update_attributes(params[:profile])

    case params[:step] # update the steps
      when "photos"
        current_user.update_attributes(:welcome => 1)
      when "basics"
        current_user.update_attributes(:welcome => 2)
      when "details"
        current_user.update_attributes(:welcome => 3)
    end

    # redirect to welcome_path before_filter determine step
    redirect_to welcome_path
  end

照片,基本和详细信息的表单只是一个form_for @profile 所以我发布它到个人资料,但想把它发布到欢迎控制器:(

最好的办法是什么?完全坚持这个

1 个答案:

答案 0 :(得分:1)

这个问题有两种方法可供选择。

  1. 使用会话。每个步骤都会运行几个验证,然后更新存储在会话中的一组序列化参数,直到达到最后一步。我不是这个人的忠实粉丝,但它适用于简单的应用程序。
  2. 使用单个表单,带有一些js / css技巧(标签,“幻灯片式”页面,带有“下一个”和“前一个”按钮),使您的表单感觉不那么麻烦。这并不适用于所有问题,但我发现很多时候多步骤表格并不需要多次往返,而且这是一种使用户体验更好的方法。
  3. 将之前步骤中的所有参数序列化为隐藏输入字段。不是一个好主意,但同样,它可以“适用于小型应用程序。”
  4. 创建一个“多步骤表单”模型,作为每个州具有不同验证的状态机。在每个步骤中,保存模型(在数据库中或在内存缓存中),以便您拥有可以提供给下一个表单的ID。每次成功保存也会将状态更改为适当的步骤。这种方法的问题是如何处理“废弃”的表单,你必须以某种方式销毁(使用cron作业来清理数据库,或使用你的内存缓存过期设置)。