Rails 5-无法使用as_json渲染关联

时间:2018-10-14 23:35:24

标签: ruby-on-rails json api

说明:
我有2个模型,分别是用户模型和兴趣模型,由has_and_belongs_to_many关联。创建用户后,我需要创建所有兴趣并进行正确的关联。它是一个API,因此我使用as_json来呈现响应,但是由于某些原因,当我删除以前的关联(self.interests.delete_all)并在associate_interests方法内创建新的关联时,它们不呈现给响应。如果删除“ self.interests.delete_all”,它将呈现所有关联的兴趣。
我找不到与此问题相关的帖子。 谢谢。

迁移

class CreateUsers < ActiveRecord::Migration[5.2]
    def change
        create_table :users do |t|
            t.string :avatar
            t.string :description
            t.string :email
            t.string :institution
            t.string :name
            t.string :orcid
            t.string :password_digest
            t.string :research_area
            t.string :username
            t.timestamps
        end

        create_table :interests do |t|
            t.string :hashtag, unique: true
            t.timestamps
        end

        create_table :interests_users, id: false do |t|
            t.belongs_to :user, index: true
            t.belongs_to :interest, index: true
        end

        add_index :interests_users, [:user_id, :interest_id], unique: true
    end
end

UserController创建方法

def create
    params = user_params
    @user = User.new(params.except(:interests))

    if @user.save
      @user.associate_interests(params[:interests]) if params.key?(:interests)
      render @user.info, status: :created
    else
      render json: @user.errors, status: :bad_request
end

用户模型

require "file_size_validator"

class User < ApplicationRecord
    has_secure_password
    has_and_belongs_to_many :interests
    validates_presence_of :username, :name, :orcid, :research_area, :institution
    validates_uniqueness_of :username, :email, :orcid
    validates :avatar, file_size: { maximum: 2.megabytes }

    mount_uploader :avatar, AvatarUploader

    def info
        as_json(
            except: [:password_digest, :avatar],
            include: [:interests, {
                avatar: {
                    only: :url
                }
            }])
    end

    def associate_interests(s_interests)
        # Have all interest models and create if they dont exist
        self.interests.delete_all

        ints = []
        s_interests.each do |hashtag|
            i = Interest.new(hashtag: hashtag)
            if i.save
                ints.push(i)
            else
                ints.push(Interest.find_by(hashtag: hashtag))
            end
        end

        # Create association between user and interests
        ints.each do |i|
            i.users.push(self)
        end
    end
end

回应self.interests.delete_all

{
    "id": 1,
    "name": "example",
    "username": "example",
    "email": "example@gmail.com",
    "institution": "UCcccccaaaaaaaafdasfadsfadsfadsafaa",
    "orcid": "123213213213",
    "research_area": "bbb",
    "description": "helloo its me",
    "created_at": "2018-10-14T22:56:26.833Z",
    "interests": []
}

没有self.interests.delete_all的响应

{
    "id": 1,
    "name": "example",
    "username": "example",
    "email": "example@gmail.com",
    "institution": "UCcccccaaaaaaaafdasfadsfadsfadsafaa",
    "orcid": "123213213213",
    "research_area": "bbb",
    "description": "helloo its me",
    "created_at": "2018-10-14T23:25:47.976Z",
    "interests": [
        {
            "id": 1,
            "hashtag": "aaaa",
            "created_at": "2018-10-14T23:25:47.999Z"
        },
        {
            "id": 2,
            "hashtag": "bbbb",
            "created_at": "2018-10-14T23:25:48.004Z"
        }
    ]
}

1 个答案:

答案 0 :(得分:0)

您正在将用户添加到兴趣的反向users关联中,但是由于该集合已经加载一次,因此用户本身仍然不知道这一事实。

您可以将代码从i.users.push(self)更改为interests << i,也可以在方法末尾添加interests.reload来从数据库中加载更改。