Search code examples
rustnearprotocol

One to many relationship in NEAR protocol using rust


I am trying to use one to many relationships using near_sdk Map and Vector.

use near_sdk::collections::Map;
use near_sdk::collections::Vector;

#[near_bindgen]
#[derive(Default, BorshDeserialize, BorshSerialize)]
pub struct ProfileDetails {
    profileTags: Map<String, IdProducts>,
}

#[near_bindgen]
#[derive(Default, BorshDeserialize, BorshSerialize)]
pub struct Products { 
    product_name: String,
    product_details: String,
} 

#[near_bindgen]
#[derive(Default, BorshDeserialize, BorshSerialize)]
pub struct IdProducts {
      products: Vector<Products>,
}

With rust native collections it's done using push method e.g.

 let mut hash_map: HashMap<u32, Vec<Sender>> = HashMap::new()
 hash_map.entry(3)
      .or_insert_with(Vec::new)
      .push(sender)

How to push using near protocol collections?

#[near_bindgen]
impl ProfileDetails {
    pub fn set_profile(&mut self, product_name:String, product_details:String) {
        let account_id = env::signer_account_id();
        p = Products {
            product_name,
            product_details
        };
        self.profileTags.insert(&account_id, ???);

    }
}

Solidity example is here: https://ethereum.stackexchange.com/a/39705/56408


Solution

  • First of all you can only have #[near_bindgen] on one struct which represents the contract itself. To implement set_profile, you can create a persistent vector with a proper prefix (account_id for example). So it would look like

    let account_id = env::signer_account_id();
    p = Products {
        product_name,
        product_details
    };
    let mut id_products = Vector::new(account_id.into_bytes());
    id_products.push(&p);
    self.profileTags.insert(&account_id, &id_products);
    

    If your collection is small, you can also use Vec from standard library.