【问题标题】:Nested devise form not linking models嵌套设计形式不链接模型
【发布时间】:2013-01-02 16:41:52
【问题描述】:

我正在尝试以相同的形式创建一个新位置和一个设计用户并将它们链接起来。用户和位置已创建,但 location_id 未保存给用户。 user 表中有一个 location_id 列。

我的表格

<% resource.build_location %>
<%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => {:class => 'form-vertical' }) do |f| %>
 <%= f.error_notification %>
 <!-- capture location details hidden values -->
  <%= f.fields_for :location do |location_form| %>
  <%= location_form.text_field :name, :name => "name", :type => "hidden" %>
  <%= location_form.text_field :street_address, :name => "formatted_address", :type => "hidden" %>
  <%= location_form.text_field :lat, :name => "lat", :type => "hidden" %>
  <%= location_form.text_field :long, :name => "lng", :type => "hidden" %>
<% end %>
 <!-- devise user authenticate --> 
  <%= f.input :name, :autofocus => true %> 
  <%= f.input :email, :required => true %>
  <%= f.input :password, :required => true %>
  <%= f.input :password_confirmation, :required => true %>
  <%= f.button :submit, 'Sign up', :class => 'btn-primary' %>
<% end %>
<%= render "devise/shared/links" %>

定位模型

class Location < ActiveRecord::Base
  has_many :users, :dependent => :destroy
  accepts_nested_attributes_for :users, :allow_destroy => true
  attr_accessible :lat, :long, :name, :street_address
  attr_accessible :user_attributes
end

位置控制器

def new
    @location = Location.new
    @location.user.build
    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @location }
    end
  end

  # GET /locations/1/edit
  def edit
    @location = Location.find(params[:id])
  end

  # POST /locations
  # POST /locations.json
  def create
    @location = @user.location.build(params[:location])
    respond_to do |format|
      if @location.save
        format.html { redirect_to @location, notice: 'Location was successfully created.' }
        format.json { render json: @location, status: :created, location: @location }
      else
        format.html { render action: "new" }
        format.json { render json: @location.errors, status: :unprocessable_entity }
      end
    end
  end

用户模型

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

  # Setup accessible (or protected) attributes for your model
  attr_accessible :role_ids, :as => :admin
  attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :location, :location_id, :location_attributes
end

用户控制器

class UsersController < ApplicationController
  before_filter :authenticate_user!

  def index
    authorize! :index, @user, :message => 'Not authorized as an administrator.'
    @users = User.all
  end

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

  def update
    authorize! :update, @user, :message => 'Not authorized as an administrator.'
    @user = User.find(params[:id])
    if @user.update_attributes(params[:user], :as => :admin)
      redirect_to users_path, :notice => "User updated."
    else
      redirect_to users_path, :alert => "Unable to update user."
    end
  end

  def destroy
    authorize! :destroy, @user, :message => 'Not authorized as an administrator.'
    user = User.find(params[:id])
    unless user == current_user
      user.destroy
      redirect_to users_path, :notice => "User deleted."
    else
      redirect_to users_path, :notice => "Can't delete yourself."
    end
  end
end

创建用户时没有错误,只是在创建用户时得到一个 location_id="nil"。我可以访问该位置并创建了一个 location_id 但未链接到用户。关于如何将 location_id 保存给用户的任何想法?

我正在使用从 google 位置 api 自动完成返回的 json 填充位置信息,并分配给 name="" 的元素。当我手动输入位置信息时,似乎一切正常,但从自动完成填充字段时失败。

【问题讨论】:

    标签: javascript ruby-on-rails devise nested-forms google-places-api


    【解决方案1】:

    首先要注意的是,这两种模型都不需要accepts_nested_attributes_for,只有具有has_many 关联的模型。此外,用户属性的位置模型中的复数形式似乎是错误的

    class Location < ActiveRecord::Base
      has_many :users, :dependent => :destroy
      accepts_nested_attributes_for :users, :allow_destroy => true
      attr_accessible :lat, :long, :name, :street_address
      attr_accessible :users_attributes # <- This should be plural
    end
    

    删除用户模型中的accepts_nested_attributes_for

    class User < ActiveRecord::Base
      belongs_to :location
      accepts_nested_attributes_for :location # <- This should be removed
      rolify
      # Include default devise modules. Others available are:
      # :token_authenticatable, :confirmable,
      # :lockable, :timeoutable and :omniauthable
      devise :database_authenticatable, :registerable,
             :recoverable, :rememberable, :trackable, :validatable
    
      # Setup accessible (or protected) attributes for your model
      attr_accessible :role_ids, :as => :admin
      attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :location, :location_id # Also remove location_atributes
    end
    

    还有这一行

    @location = @user.location.build(params[:location])
    

    应该是

    @location = Location.new(params[:location)
    

    由于您的模型设置方式现在一个位置有一个用户,因此您不需要从用户构建一个位置。话虽如此,我建议您在用户拥有多个位置的相反方向创建关联,但这当然可能与您的功能相反,因此请谨慎对待:)。

    http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

    【讨论】:

    • 感谢 Jason,问题是如果我在用户模型中删除 Accepts_nested_attributes_for,我会收到此错误:ActiveRecord::AssociationTypeMismatch in DeviseInvitable::RegistrationsController#create Location(#70224765161800) expected, got ActiveSupport:: HashWithIndifferentAccess(#70224763369340)
    • UsersController 可能存在问题。由于您使用的是设计,因此实际上根本不需要一个,如果您想覆盖设计提供的功能,则必须覆盖其控制器本身。请参阅此内容:github.com/plataformatec/devise#configuring-controllers。如果您不这样做,您可能还想从用户模型中删除 :locationlocation_attributes
    • 谢谢 Jason,我会看看那个。我确信有更好的方法可以做到这一点,尽管我仍然有点困惑为什么当我手动将数据输入到 text_field 时它会起作用,但当相同的 text_field 接收到 json 文本时它不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多