如何改进这些控制器代码以更好地通过数据库设计实现has_many?

时间:2013-12-11 10:55:02

标签: ruby-on-rails

以下是我的模特:

class Item < ActiveRecord::Base
    has_many :item_categoryships
    has_many :categories, :through => :item_categoryships

    belongs_to :user

    validates :title, presence: true
end

class Category < ActiveRecord::Base
    has_many :item_categoryships
    has_many :items, :through => :item_categoryships

    belongs_to :user

    validates :name, presence: true
end


class ItemCategoryship < ActiveRecord::Base
    belongs_to :item
    belongs_to :category
    validates :item_id, presence: true
    validates :category_id, presence: true
end


class User < ActiveRecord::Base
    has_many :items
    has_many :categories, class_name: 'Category'
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable, :confirmable, :async
end

在我的项目控制器中,有以下代码:

def edit
    @item = current_user.items.find(params[:id])
    @categories = current_user.categories
end

def update
    @item = current_user.items.find(params[:id])

    if @item.update_attributes(item_params) 
            params[:item][:category_ids].map{|x| x.to_i }.each do |category_id|
                category = ItemCategoryship.new(item_id: @item.id, category_id: category_id)
                category.save unless category.category_id <= 0
            end

            flash[:success] = "item updated successfully!"      
            redirect_to items_path
    else
        render 'edit'
    end
end

我的 views / items / edit.html.erb

    <%= simple_form_for(@item) do |f| %>
            <%= f.input :title, :label => "title" %>
            <%= f.input :description, :as => :text, :label => "description" %>
            <%= f.select :category_ids, @categories.collect {|x| [x.name, x.id]}, {}, :multiple => true %>
            <%= f.submit 'submit', class: 'btn bnt-large btn-primary' %>
    <% end %>
我希望数据库只能有用户选择的内容,如果用户选择了两个类别,那么ItemCategoryship表只有两条记录,如果用户取消其中一条,那么该记录就从表中销毁。

如何以简洁的方式改进我的代码以实现此功能?

谢谢大家。

1 个答案:

答案 0 :(得分:0)

我认为这应该足够了,不需要另外添加Item Category Ship。

def update
    @item = current_user.items.find(params[:id])
    if @item.update_attributes(param[:item])    
      flash[:success] = "item updated successfully!"      
      redirect_to items_path
    else
      render 'edit'
    end
end