Ruby on rails 当记录不为’时,创建带有标记的新记录(有多个到);他还没有坚持

Ruby on rails 当记录不为’时,创建带有标记的新记录(有多个到);他还没有坚持,ruby-on-rails,has-many-through,Ruby On Rails,Has Many Through,我想实现自定义标记功能。到目前为止,我有项目和标记模型,但我很难提交标记–Rails一直告诉我,每当我尝试创建新的项目时,标记分配无效 (新项目的创建表示项目描述的文本区域和带有db中所有现有标记的一组复选框。) 奇怪的是,更新现有项目的标签效果很好。这一观察结果使我发现,罪魁祸首实际上在于,在构建过程中,项对象没有持久化,因此它还没有id,因此目前无法建立项和标记之间的关系 基于此,我在ItemsController中增加了create操作,使用了以下装置。 虽然这是可行的,但对我来说,这似乎

我想实现自定义标记功能。到目前为止,我有
项目
标记
模型,但我很难提交标记–Rails一直告诉我,每当我尝试创建新的
项目
时,标记分配无效

(新项目的创建表示项目描述的文本区域和带有db中所有现有标记的一组复选框。)

奇怪的是,更新现有项目的标签效果很好。这一观察结果使我发现,罪魁祸首实际上在于,在构建过程中,项对象没有持久化,因此它还没有
id
,因此目前无法建立项和标记之间的关系

基于此,我在
ItemsController
中增加了
create
操作,使用了以下装置。 虽然这是可行的,但对我来说,这似乎是一种丑陋的黑客行为,所以我想知道正确的方法是什么™ 来处理这种情况

class ItemsController < ApplicationController
⋮
  def create
    tags = {}
    tags[:tag_ids] = item_params.delete('tag_ids')
    reduced_params = item_params.reject{|k,v| k == 'tag_ids'}
    @item = current_user.items.build(reduced_params)
    @item.save
    @item.update_attributes(tags)
_item_form.html.erb

⋮
<section class="tag_list">
  <%= f.collection_check_boxes :tag_ids, Tag.all, :id, :name do |cb| %>
      <% cb.label {cb.check_box + cb.text} %>
  <% end %>
</section>

我建议使用gem。它解决了几乎所有关于标签使用的情况

class User < ActiveRecord::Base
  acts_as_taggable # Alias for acts_as_taggable_on :tags
  acts_as_taggable_on :skills, :interests
end

class UsersController < ApplicationController
  def user_params
    params.require(:user).permit(:name, :tag_list) ## Rails 4 strong params usage
  end
end

@user = User.new(:name => "Bobby")

@user.tag_list.add("awesome")   # add a single tag. alias for <<
@user.tag_list.remove("awesome") # remove a single tag
class用户“Bobby”)

@user.tag_list.add(“awesome”)#添加单个标记。alias for您可能希望使用虚拟属性,在本例中为标记列表,它将使用数据库中存在的新标记或已创建和持久化标记

class Item < ApplicationRecord
  def tag_list
    self.tags.collect do |tag|
    tag.name
    end.join(", ")
   end

   def tag_list=(tags_string)
    tag_names = tags_string.split(",").collect{|s| s.strip.downcase}.uniq
    new_or_found_tags = tag_names.collect { |name| Tag.find_or_create_by(name: name) }
    self.tags = new_or_found_tags
   end
现在,您的项目新建和创建操作可以像

def new
    @item = Item.new
end

def create
    @item = Item.new(item_params)
    @item.save
    redirect_to ......
end

我在寻找解决方案时遇到了这个宝石。但这个问题更多的是关于我对如何处理这种情况的好奇,而不是让它发挥作用。
⋮
<section class="tag_list">
  <%= f.collection_check_boxes :tag_ids, Tag.all, :id, :name do |cb| %>
      <% cb.label {cb.check_box + cb.text} %>
  <% end %>
</section>
class User < ActiveRecord::Base
  acts_as_taggable # Alias for acts_as_taggable_on :tags
  acts_as_taggable_on :skills, :interests
end

class UsersController < ApplicationController
  def user_params
    params.require(:user).permit(:name, :tag_list) ## Rails 4 strong params usage
  end
end

@user = User.new(:name => "Bobby")

@user.tag_list.add("awesome")   # add a single tag. alias for <<
@user.tag_list.remove("awesome") # remove a single tag
class Item < ApplicationRecord
  def tag_list
    self.tags.collect do |tag|
    tag.name
    end.join(", ")
   end

   def tag_list=(tags_string)
    tag_names = tags_string.split(",").collect{|s| s.strip.downcase}.uniq
    new_or_found_tags = tag_names.collect { |name| Tag.find_or_create_by(name: name) }
    self.tags = new_or_found_tags
   end
 <%= f.label :tag_list %><br />
 <%= f.text_field :tag_list %>
private

  def item_params
    params.require(:item).permit(:description, :tag_list)
  end
def new
    @item = Item.new
end

def create
    @item = Item.new(item_params)
    @item.save
    redirect_to ......
end