Bro Faz Sol
Bro Faz Sol

Reputation: 83

Problems with SQLITE columns (array) in Rails

I'm building an API, I have 2 models User and Coin.

The Coins table stores the default coins that can be added to the user's account.

I need to save the coins ids that the user decided to add in a column of the User model (my_coins), and be able to list only the coins saved by the user. The problem is that I'm using sqlite3 and I can't save an array in a column

Routes.rb

get '/getCoins', to: "coins#index"
post '/coin/add', to: "users#add_coin"

users_controller.rb

class Api::V1::UsersController < ApplicationController
    before_action :validate_jwt # Validates JWT, @current_user
    before_action :user_coins_params

    def add_coin
        coin_acronym = user_coins_params[:id]
        if Coin.find(coin_acronym).exists?

            # @current_user CURRENT USER LOGGED IN ACTIVE RECORD
            # ADD THE ID OF COIN TO MY_COINS COLUMN            

            if # push id of coin to my_coins column success 
                render json: { success: true, message: "Moeda cadastrada com sucesso!" }
            else 
                render json: { success: false, errors: @current_user.errors }
            end
        else
            render json: { success: false, message: "Moeda não encontrada" }
        end
    end

    private
        def user_coins_params
            ActiveModelSerializers::Deserialization.jsonapi_parse!(params)
        end
end

coins_controller.rb

class Api::V1::CoinsController < ApplicationController
  before_action :validate_jwt # VALIDATES JWT, @current_user
  before_action :set_coin, only: [:show, :update, :destroy]

  # /coins GET USER COINS 
  def index    
    @coins = # GET USER COINS (@current_user.my_coins.each { |coinId| ... })
    render json: @coins, include: [:mining_type]
  end

end

Upvotes: 0

Views: 78

Answers (1)

r4cc00n
r4cc00n

Reputation: 2117

As pointed above by @spickermann, seems like what you need is a has and belongs to many associations (HBTM) in both models users and coins, I think this approach is a better fit for your problem, is easy to get/update/create any data with this approach, at least I think is better than an array inside a column of your users table, in case you want to give it a try here is how I will do it:

So on your coin model add the following line: has_and_belongs_to_many :users; and in your user model: has_and_belongs_to_many :coins.

Once you added the proper associations to your models you need to generate a migration in order to create your join table, the code in the migration should look like below:

create_join_table :users, :coins do |t|
      t.index [:user_id, :coin_id]
      t.index [:coin_id, :user_id]
end

The example above is on rails 5.2, and with the above, you can do stuff like:

user1.coins << coin_a
user1.save

Then you can iterate over user1.coins if you want all the coins related to a particular user (This link might be helpful).

Hope the above helps 👍!

Upvotes: 1

Related Questions