【问题标题】:Error: undefined method `each' for "1":String错误:“1”的未定义方法“每个”:字符串
【发布时间】:2014-12-12 12:22:47
【问题描述】:

我正在尝试将模型 Thing 与我的 things/new 表单上的另一个 Thing 相关联。每个 Thing has_many :things 通过一个连接表 :related_things。

当我提交表单时,我收到此错误:

NoMethodError in ThingsController#create
undefined method `each' for "1":String

我的代码哪里出错了?

Thing model:我在错误消息的行周围加上了星号。

class Thing < ActiveRecord::Base
  has_many :related_things
  has_many :things, :through => :related_things
  has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "30x30!" }, :default_url => "/images/:style/missing.png"
  validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/

  def related_things
    related_thing_ids = RelatedThing.
        where("thing_a_id = ? OR thing_b_id = ?", self.id, self.id).
        map { |r| [r.thing_a_id, r.thing_b_id] }.
        flatten - [self.id]
    Thing.where(id: related_thing_ids)
  end
  def related_thing_ids=(ids)
    ***ids.each do |id|***
      record = RelatedThing.where(thing_a_id: self.id, thing_b_id: id).first
      record ||= RelatedThing.where(thing_a_id: id, thing_b_id: self.id).first
      record ||= RelatedThing.create!(thing_a_id: self.id, thing_b_id: id)
    end
  end
end

RelatedThing模特:

class RelatedThing < ActiveRecord::Base
  has_many :things
end

Things控制器:

class ThingsController < ApplicationController
  def show
    @thing = Thing.find(params[:id])
    @related_thing = RelatedThing.all
    @thing.things.build
  end
  def new
    @thing = Thing.new
    @things = Thing.all
  end
  def create
    @thing = Thing.new(thing_params)
    if @thing.save
      redirect_to @thing
    else
      render 'new'
    end
  end

  private
  def thing_params
    params.require(:thing).permit(:name, :avatar, :related_thing_ids)
  end
end

事物/new.html.erb:

<h1>Add Something!</h1>
<p>
  <%= form_for @thing, :url => things_path, :html => { :multipart => true } do |f| %>
    <%= f.text_field :name, :placeholder => "Name of the thing" %>
    <br>
    <%= f.label :related_things %>
    <%= f.collection_select :related_thing_ids, Thing.all, :id, :name %>
    <br>
    <%= f.label :display_picture %>
    <%= f.file_field :avatar %>
    <br>
    <%= f.submit "Submit", class: "btn btn-primary" %>
  <% end %>
</p>

Schema.rb:

ActiveRecord::Schema.define(version: 20141016190146) do
  create_table "related_things", force: true do |t|
    t.integer  "thing_a_id"
    t.integer  "thing_b_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end
  create_table "things", force: true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "avatar_file_name"
    t.string   "avatar_content_type"
    t.integer  "avatar_file_size"
    t.datetime "avatar_updated_at"
  end
end

我使用的是 Rails 4.0.10。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 methods associations


    【解决方案1】:

    试试Array(ids).each ...,它转换数组中的任何对象并响应:each

    ~ (main) > Array(nil)
    => []
    ~ (main) > Array([])
    => []
    ~ (main) > Array('')
    => [""]
    ~ (main) > Array(1)
    => [1]
    

    Kernel#Array

    【讨论】:

    • 在related_thing_ids 下?您将如何实现它?
    • 将用**创建的行更改为:Array(ids).each do |id|。这必须修复 NoMethodError。 BDW,您似乎只对一个模型存在多对多关系:“事物”。请阅读 (guides.rubyonrails.org/v4.0.8/association_basics.html),并查看 (github.com/mhartl/sample_app/blob/master/app/models) relationship.rb 和 user.rb,这是使用这种关联的 Rails 方式的一个很好的例子。之后,再对代码进行一些重构,就完全不用写方法related_thing_ids=了。
    猜你喜欢
    • 2014-10-10
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 2015-10-12
    • 1970-01-01
    • 2015-01-29
    • 1970-01-01
    相关资源
    最近更新 更多