代码之家  ›  专栏  ›  技术社区  ›  Marcius Leandro

在Ruby on Rails中创建一个具有多对多关系的帖子

  •  0
  • Marcius Leandro  · 技术社区  · 10 年前

    我有一个非常适合分类和叫喊的结构。我所做的是用以下参数qeuro调用POST类型的API:

    {
        "user_id":"1",
        "title":"primeito",
        "desciption":"de_novo",
        "categories":[{"name":"eletro"},{"name":"domestic"},{"name":"new_category"}],
        "yell_type":"novo",
        "price":"10,00",
        "payment_type":"boleto"
    }
    

    我的结构如下:

    我的模特大喊:

    #yell.rb
    class Yell < ActiveRecord::Base
      belongs_to :user, inverse_of: :yells
      has_and_belongs_to_many :categories
    end
    

    型号类别:

    #category.rb
    class Category < ActiveRecord::Base
      has_and_belongs_to_many :yells
    end
    

    控制器中的方法混凝土喊道:

    #yells_controller.rb
    def create
    @yell = Yell.new(yell_params)
    
    params[:categories].each do |rel|
      @category = Category.find_by_name(rel[:name])
      if @category
        #only creates the relationship
      else
        @yell.categories.build(name: rel[:name]) #creates the relationship and category
      end
    end
    
    if @yell.save
         render json: @yell, status: :created, location: api_yell_path(@yell)
       else
         render json: @yell.errors, status: :unprocessable_entity
       end
    end
    ...
    private:
    
        def yell_params
          params.require(:yell).permit(:title, :desciption, :price, :payment_type, :user_id, :yell_type, :categories)
        end
    

    所以我创建了表格

    class CreateCategoriesYellsJoinTable < ActiveRecord::Migration
      def self.up
        create_table :categories_yells, :id => false do |t|
          t.integer :category_id
          t.integer :yell_id
        end
    
        add_index :categories_yells, [:category_id, :yell_id]
      end
    
      def self.down
        drop_table :categories_yells
      end
    end
    

    我可以让他创建类别,但不知道如何只创建关系。Agluem可以帮助我的是,评论#只创建了关系吗?

    我需要进行此检查,因为类别名称是唯一的

    如果有人知道更优雅的方法,我会接受建议

    2 回复  |  直到 10 年前
        1
  •  0
  •   Arturo Diaz    10 年前

    我不太确定我是否理解了最后一段,但我认为首先需要一个中间表来连接这两个模型。

    您需要创建如下表:

    class CreateCategoriesAndYells < ActiveRecord::Migration
      def change
        create_table :categories_yells, id: false do |t|
          t.belongs_to :category, index: true
          t.belongs_to :yell, index: true
        end
      end
    end
    

    然后,您需要更新您的控制器以说出以下内容:

    @yell.categories.build(category_params)
    

    您还需要将类别参数传递给控制器。

        2
  •  0
  •   Marcius Leandro    10 年前

    为了做到这一点,我必须创建一个模型来加入我的表:

    型号category_yell.rb

    class CategoriesYell < ActiveRecord::Base
      belongs_to :category
      belongs_to :yell
    end
    

    create 我的方法如下:

    def create
      #@yell = Yell.new(yell_params.except(:categories))
      @yell = Yell.new({title: params[:title], desciption: params[:desciption], price: params[:price], user_id: params[:user_id], yell_type: params[:yell_type]})
    
      if @yell.save
        Array(params[:categories]).each do |rel|
    
          @category = Category.find_by_name(rel[:name])
    
          if @category
            @categories_yells = CategoriesYell.new(category_id: @category.id, yell_id: @yell.id)
    
            if @categories_yells.save
              @yell.categories.build(id: @category.id, name: rel[:name])#only creates the relationship
            else
              render json: {status: 1, message:"relationship categoy not create", data: @yell.errors}, status: :unprocessable_entity
            end
    
          else
            @yell.categories.create(name: rel[:name]) #creates the relationship and category
          end
    
        end
    
        render json: {status: 0, message:"sucess", data: @yell}, status: :created
      else
        render json: {status: -1, message:"error", data: @yell.errors}, status: :unprocessable_entity
      end
    
    end
    
    推荐文章