【问题标题】:Adding nested attributes to devise user model添加嵌套属性以设计用户模型
【发布时间】:2013-05-03 23:03:09
【问题描述】:

乍一看,这个问题似乎以前已经回答过了,但在我的情况下却没有(大多数都与批量分配问题和/或 mongoid 有关。)即使有很多问题,我也无法找到答案相关问题在这里。

所以基本上我在 ruby​​ on rails 应用程序上使用 devise gem 进行用户身份验证,我想向用户模型添加一个嵌套地址模型。我也在使用 simple_form 来生成表单视图。

我有一个用户模型:

class User < ActiveRecord::Base
  has_and_belongs_to_many :roles
  has_one :address

  accepts_nested_attributes_for :address, :allow_destroy => true
end

这是地址模型:

class Address < ActiveRecord::Base
  belongs_to :country
  belongs_to :state
  belongs_to :user

  attr_accessible :street1, :street2, :country_id, :state_id, :city, :postalCode
end

这是用户控制器,我重写它是为了添加一个显示操作来显示用户配置文件。

class Users::RegistrationsController < Devise::RegistrationsController
  def new
    resource = build_resource({})
    resource.build_address
    respond_with resource
  end

  # POST /resource
  def create
    resource = build_resource(params[:user])

    if resource.save
      if resource.active_for_authentication?
        set_flash_message :notice, :signed_up if is_navigational_format?
        sign_up(resource_name, resource)
        respond_with resource, :location => after_sign_up_path_for(resource)
      else
        set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
        expire_session_data_after_sign_in!
        respond_with resource, :location => after_inactive_sign_up_path_for(resource)
      end
    else
      clean_up_passwords resource
      respond_with resource
    end
  end

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

    #Add to view count if not viewing own user profile
    if @user != current_user
      @user.views += 1
      @user.save  
    end

    @vehicles = Vehicle.where(:user_id => @user)

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @user }
    end
  end
end

这是创建新用户的视图:

<%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name) ) do |f| %>

              <fieldset>
                    <%= f.input :username, :required => false, :autofocus => true, placeholder: 'Pick a username' %>
                    <%= f.input :email, :required => false, placeholder: 'Your email' %>
                    <%= f.input :password, :required => false, placeholder: 'Create a password' %>
                    <%= f.input :password_confirmation, :required => false, placeholder: 'Confirm your password' %>
                    <%= f.association :roles, :as => :check_boxes, :label => "", :required => false %>
                    <%= f.simple_fields_for :address do |a| %>
                        <%= a.input :street1 %>
                        <%= a.input :street2 %>
                        <%= a.association :country %>
                        <%= a.association :state %>
                        <%= a.input :city %>
                        <%= a.input :postalCode %>
                    <% end %>
                    <%= f.button :submit, 'Sign up for free', :class => 'btn btn-success btn-large' %>
              </fieldset>
<% end %>

所以创建新用户时的错误是这样的: 地址用户不能为空

基本上没有为地址设置外键user_id。

我希望有人能对这个问题有所了解。

【问题讨论】:

  • 你试过设置:inverse_of的用户和地址关系吗?
  • 另一种可以确保设置user_id 的方法是在UsersController#new 操作中设置@address = @user.build_address,然后在表单中使用@address 作为嵌套表单的对象。请记住,无论如何,您都将为每个用户创建一个地址。
  • 嗨,安迪!我考虑了这两个建议。 :inverse_of 什么也没做,同样的问题。然后我按照建议更改了新的操作和视图字段,现在我得到以下异常:ActiveRecord::AssociationTypeMismatch in Users::RegistrationsController#create

标签: ruby-on-rails ruby attributes devise nested


【解决方案1】:

我能够在我的应用程序中解决这个问题,但我使用了强参数。但是,该解决方案仍应适用于您的情况。

我没有重写 RegistrationsController 中的所有方法,而是重写了 build_resource 以传入所需的正确参数。

def build_resource(params)
  super(resource_params)
end

def resource_params
  params.require(:user).permit(:email, :password, tickets_attributes: [ :description ] )
end

我的UserTicket 型号上也有inverse_of,就像这样:

user.rb
  has_many :tickets, inverse_of: :user

ticket.rb
  belongs_to :user, inverse_of :tickets

【讨论】:

  • 嗨,杰夫,我从来没有让这个工作,我会尝试你的解决方案并尽快报告。感谢您提出解决方案。
【解决方案2】:

忘记添加 user_id 来解决迁移问题。 Rails 在将 belongs_to :user 添加到地址模型时期望它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    相关资源
    最近更新 更多