【问题标题】:Rails 4, Devise & Polymorphic AssociationsRails 4,设计和多态关联
【发布时间】:2013-09-30 21:22:14
【问题描述】:

这是我通过 Rails 4 JSON API 注册一种名为导师的用户的功能代码。

现在我想知道,有没有更好的方法来解决这个问题?一种更清洁/更简单的方法,Rails 可以自动创建用户/导师关联。

目前我在create 方法中手动设置它,这似乎不正确。所以我只是想确保没有更好的方法来解决这个问题。

models/user.rb

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

  belongs_to :role, :polymorphic => true
end

models/mentor.rb

class Mentor < ActiveRecord::Base
  has_one :user, as: :role
  accepts_nested_attributes_for :user
end

controllers/api/V1/mentors_controller.rb

class Api::V1::MentorsController < ApplicationController
  respond_to :json

  def create
    @user = User.new(user_params)
    @mentor = Mentor.new(mentor_params)
    @user.role = @mentor
    @user.save!
    @mentor.user_id = @user.id
    @mentor.save!
    respond_with :api, @mentor
  end

  private

  def mentor_params
    params.require(:mentor).permit(:first_name, :last_name)
  end

  def user_params
    params.require(:user).permit(:email, :password)
  end
end

更新 - 2013 年 10 月 1 日

我在这方面取得了更多进展。这是我现在拥有的:

controllers/api/V1/mentors_controller.rb

class Api::V1::MentorsController < ApplicationController
  respond_to :json

  def create
    @mentor = Mentor.new(mentor_params)
    @mentor.user.save!
    @mentor.user_id = @mentor.user.id
    @mentor.save!
    respond_with :api, @mentor
  end

  private

  def mentor_params
    params.require(:mentor).permit(:first_name, :last_name, user_attributes: [:email, :password])
  end
end

但我仍然需要手动设置 user_id。只做Mentor.create(mentor_params) 设置user_id 失败。有什么办法可以解决吗?

【问题讨论】:

  • 您是否尝试在用户中创建mentor= 方法? Rails 应该采用 params[:user][:mentor] 并将其传递给 mentor= 方法。然后你可以构建你的 Mentor.new 并在你的用户类中做所有其他的事情。你的控制器应该变成@user = User.new(user_params)@user.save!respond_with :api, @user.mentor
  • @jeremywoertink 我不想把所有东西都放在一个用户控制器中。我将有几个具有不同字段的不同用户类型。所以我宁愿将逻辑分离到他们自己的控制器中。

标签: ruby devise ruby-on-rails-4 polymorphic-associations


【解决方案1】:

这不是我的想法,但基本想法是这样的。

使用嵌套资源创建表单

form_for @mentor do |f|
  f.input :mentor_val
  f.fields_for :user do |m|
    m.input :user_val

它应该发布一个具有如下格式的 params 对象:

mentor: {
  mentor_val: 'blah'
  user_attributes: {
    user_val: 'foo'
  }
}

现在,由于您已将 accepts_nested_attributes_for 包含在 Mentor 模型中,Rails 自动向 Mentor 添加了一个 user_attributes= 方法,该方法将构建用户模型,包括设置关系。这意味着要创建两个模型,您只需在控制器中调用

@mentor.create(params)

【讨论】:

  • 我实际上尝试了这种方法,但它完全忽略了用户参数并且没有在两者之间创建任何关联。与this person类似的经历。
  • 我意识到我在请求中错误地命名了属性。所以你的建议有效,但只是部分有效(见上文)。
【解决方案2】:

要回答有关更新的问题,请尝试将 id 添加到您的参数白名单中:

def mentor_params
    params.require(:mentor).permit(:first_name, :last_name,user_attributes: [:id, :email, :password])
end

【讨论】:

    猜你喜欢
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 2014-12-16
    • 1970-01-01
    相关资源
    最近更新 更多