4

我有这些模型:

class User < ActiveRecord::Base
    has_one :city
    accepts_nested_attributes_for :city
end

class City < ActiveRecord::Base
    belongs_to :user
end

此控制器操作:

   def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        format.html { redirect_to(@user, :notice => 'User was successfully created.') }
        format.xml  { render :xml => @user, :status => :created, :location => @user }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
      end
    end
  end

这个观点:

<%= form_for :user,:url => users_path,:method => :post do |f| %>
<%= f.fields_for :city do |b| %>
    <%= b.collection_select :id,City.all,:id,:name %>
  <% end %>

  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

我试图让用户从已添加的城市列表中选择一个城市。我正试图向他展示一个选择。它可以工作的选择部分,但为其生成的 html 代码如下所示:

<select name="user[city][id]" id="user_city_id">
   <option value="1">One</option>
   <option value="2">Two</option>
</select>

请注意,它的名称没有attribute任何地方。所以,当我尝试保存它时,我收到了这个错误:

City(#37815120) expected, got ActiveSupport::HashWithIndifferentAccess(#32969916)

我怎样才能解决这个问题?

编辑:有一些进展,我试图将 fields_for 更改为:

<%= f.fields_for :city_attributes do |b| %>
    <%= b.collection_select :id,City.all,:id,:name %>
<% end %>

现在,html 似乎生成正确。但我现在收到此错误:

Couldn't find City with ID=1 for User with ID=

我不知道下一步该做什么。

EDIT2:覆盖该city_attributes=方法似乎有效:

def city_attributes=(attribs)
    self.city = City.find(attribs[:id])
end

我不知道这是否是要走的路,但它似乎很好。

4

3 回答 3

2

看看这个与你的问题相似的问题: Rails 3:“accepts_nested_attributes_for”如何工作?

实际上,既然 Cities 已经存在,我认为这里不需要嵌套表格。

尝试更换

<%= f.fields_for :city_attributes do |b| %>
    <%= b.collection_select :id,City.all,:id,:name %>
<% end %>

<%= f.collection_select :city, City.all,:id,:name %>

更新后评论

你能改变你的关系(并相应地更新数据库方案)

class User < ActiveRecord::Base
    belongs_to :city
end

class City < ActiveRecord::Base
    has_many :users
end

然后尝试使用:

<%= f.collection_select :city_id, City.all,:id,:name %>
于 2011-04-07T08:04:35.527 回答
1

你也可以做一个

<%= f.collection_select :city_id, City.all, :id, :name %>

在您的视图中,然后将虚拟属性添加到您的用户模型:

class User < ActiveRecord::Base
  ...
  def city_id(c_id)
    update_attribute(:city, City.find(c_id))
  end

  def city_id
    city.id
  end
end

这可能不是很干净,因为每当将 ID 分配给 some_user.city_id 时,关联的 City 模型都会被“保存”。但是,此解决方案使您的控制器和视图保持整洁。

注意:您可能还需要考虑将空白 ID 传递给 setter 方法。

于 2013-02-19T13:15:53.647 回答
0

尝试这个

<%= f.select(:city_id, City.all.collect {|p| [ p.name, p.id ] }) %>

于 2011-04-07T07:25:31.063 回答