Справка по полям токенов Rails «многие ко многим»

#ruby-on-rails #ruby #ruby-on-rails-3

#ruby-on-rails #ruby #ruby-on-rails-3

Вопрос:

У меня возникла проблема, которую моя модель не хочет сохранять. У меня есть поле ввода токена для тегов. Я следовал этому руководству для ввода токена: http://railscasts.com/episodes/258-token-fields

Я получаю эту ошибку, когда пытаюсь создать нового конкурсанта:

 NoMethodError in Admin/konkurrancersController#create

undefined method `class_name' for nil:NilClass

Rails.root: C:/Rails/konkurranceportalen
Application Trace | Framework Trace | Full Trace

app/models/konkurrancer.rb:15:in `tag_tokens='
app/controllers/admin/konkurrancers_controller.rb:48:in `new'
app/controllers/admin/konkurrancers_controller.rb:48:in `create'

http://pastie.org/1834194

Request

Parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"yo7wcAQl81tx3zZpPP44ENPYzYRZLpgyYKY HK3yFKM=",
 "konkurrancer"=>{"name"=>"Vind en rejse",
 "banner2"=>"asdasd",
 "tracking"=>"sadasd",
 "vaerdi"=>"12222",
 "tid"=>"1 min",
 "tag_tokens"=>"1",
 "bedom"=>"2",
 "kategori_id"=>"9",
 "form"=>"Nyhedsbrev",
 "partner"=>"Iqmedier",
 "udtraekkes(3i)"=>"30",
 "udtraekkes(2i)"=>"4",
 "udtraekkes(1i)"=>"2011",
 "udtraekkes(4i)"=>"08",
 "udtraekkes(5i)"=>"26",
 "arrangeor"=>"",
 "note"=>""},
 "commit"=>"Opret konkurrence"}
  

Моя модель конкурсанта:

 class Konkurrancer < ActiveRecord::Base
attr_accessible :name, :tag_tokens
  has_many :tagsmenus
  has_many :tags, :through => :tagsmenus
attr_reader :tag_tokens

  def tag_tokens=(ids)
    self.tag_ids = ids.split(",")
  end

end
  

Моя модель тегов:

 class Tag < ActiveRecord::Base
has_many :tagsmenus
has_many :konkurrancers, :through => :tagsmenus
has_friendly_id :name, :use_slug => true
before_save :assign_cached_slug, :unless => :cached_slug?

protected
  def assign_cached_slug
    self.cached_slug = self.name.gsub(/s /, '_').gsub(/[^w-]/, '')
  end

end
  

Моя модель tagmenu:

 class Tagsmenu < ActiveRecord::Base
end
  

Мой контроллер:

 def new
@konkurrancer = Konkurrancer.new  
respond_to do |format|
format.html # new.html.erb
format.xml  { render :xml => @konkurrancer }
end
end
  # POST /konkurrancers
  # POST /konkurrancers.xml
  def create
    @konkurrancer = Konkurrancer.new(params[:konkurrancer])

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

Я создал таблицу соединений и модель, а также добавил отношение к моей модели тегов.

Комментарии:

1. Есть ли у вас поле в модели с именем tag_ids ?

2. Я обновил свой ответ соответствующей моделью

3. Я нашел решение, определяющее взаимосвязь между тегами и конкурсантом в tagsmenus

Ответ №1:

В вашей модели есть несколько противоречивых утверждений. Сначала вы определяете:

 attr_accessor ... :tag_tokens
  

затем позже придется:

 attr_reader :tag_tokens
  

в этом нет необходимости, учитывая первую строку, или наоборот, учитывая, что позже у вас будет определение для установщика:

 def tag_tokens(ids)
  self.tag_ids = ids.split(',')
end
  

Я также не вижу tag_ids определенного значения, учитывая, что это не столбец в вашей таблице. Вероятно, вам следует удалить attr_accessor определение для tag_tokens , а затем определить tag_ids метод для начала.

Комментарии:

1. У меня нет столбца с именем tag_ids. Можете ли вы показать мне, как должна выглядеть моя модель? 🙂

Ответ №2:

 class Tagsmenu < ActiveRecord::Base
  belongs_to :konkurrancer
  belongs_to :tag
end