2014-11-19 15 views
6

Jestem nowy w Sails.js (v0.10.5) i w linii wodnej ORM. Mam 3 tabele w bazie danych: users (id, name), role (id, alias) i join users_roles (user_id, role_id). Ważne jest, aby nie zmieniać nazw tabel i nazw pól w bazie danych. Chcę, aby obiekt strategii był łącznikiem między użytkownikiem a rolą. Oto kod mapowania:Sails.js + Waterline: Many-to-Many poprzez asocjację

//User.js 
module.exports = { 
    tableName: 'users', 
    autoCreatedAt: false, 
    autoUpdatedAt: false, 
    attributes: { 
     id: { 
      type: 'integer', 
      required: true 
     }, 
     name: { 
      type: 'string' 
     }, 
     roles: { 
      collection: 'role', 
      via: 'users', 
      through: 'policy' 
     }, 
    } 
} 

//Role.js 
module.exports = { 
    tableName: "roles", 
    autoCreatedAt: false, 
    autoUpdatedAt: false, 
    attributes: { 
     id: { 
      type: 'integer', 
      required: true 
     }, 
     alias: { 
      type: 'string', 
      required: true 
     }, 
     users: { 
      collection: 'user', 
      via: 'roles', 
      through: 'policy' 
     } 
    } 
} 

//Policy.js 
module.exports = { 
    tableName: "users_roles", 
    tables: ['users', 'roles'], 
    junctionTable: true, 
    autoCreatedAt: false, 
    autoUpdatedAt: false, 
    attributes: { 
     user: { 
      columnName: 'user', 
      type: 'integer', 
      foreignKey: true, 
      references: 'user', 
      on: 'id', 
      via: 'role', 
      groupBy: 'user' 
     }, 
     roles: { 
      columnName: 'role', 
      type: 'integer', 
      foreignKey: true, 
      references: 'role', 
      on: 'id', 
      via: 'user', 
      groupBy: 'role' 
     } 
    } 
} 

Ale kiedy próbuje uzyskać dostęp do ról atribute kontroler

User.findOne({id: 1}).populate('roles').exec(function(err, user) { 
    console.log(JSON.stringify(user.roles)); 
}); 

ta zwraca

[] 

I

User.findOne({id: 1}).populate('roles').exec(function(err, user) { 
    console.log(JSON.stringify(user)); 
}); 

powraca

Sprawdziłem dwa razy, że użytkownik, rola i powiązanie między nimi istnieje w bazie danych. Jaki jest mój błąd?

+0

Czy ty proszę podać kod? Upewnij się, że robisz User.find(). Zapełnij ("role"). Exec (function() {}) –

+0

@ mandeep_m91 dziękuję za odpowiedź! Edytowałem pytanie (były pewne błędy w wynikach konsoli .log). –

+1

Czy byłeś w stanie rozwiązać ten problem? Jeśli nie, które z bazowych db używasz? –

Odpowiedz

4

Znalazłem sposób na rozwiązanie tego problemu. Nie tego chcę dokładnie, ale działa. pierwsze: przyłączenia podmiot:

//Policy.js 
module.exports = { 
    tableName: "users_roles", 
    autoPK: false, 
    attributes: { 
     id: { 
      type: 'integer', 
      primaryKey: true, 
      autoIncrement: true, 
     }, 
     user: { 
      columnName: 'user_id', 
      model: 'user' 
     }, 
     role: { 
      columnName: 'role_id', 
      model: 'role' 
     } 
    }, 
    //tricky method to get all users for specified role_id 
    //or to get all roles for specified user_id 
    get: function(id, modificator, cb) { 
     var fields = ['user', 'role']; 
     if (fields.indexOf(modificator) < 0) { 
      cb(new Error('No such modificator in Policy.get()'), null); 
     } 
     var inversedField = fields[(fields.indexOf(modificator) + 1) % 2]; 
     var condition = {}; 
     condition[inversedField] = id; 
     this.find(condition).populate(modificator).exec(function(err, policies) { 
      if (err) { 
       cb(err, null); 
       return; 
      } 
      var result = []; 
      policies.forEach(function(policy) { 
       result.push(policy[modificator]); 
      }); 
      cb(null, result); 
      return; 
     }); 
    } 
} 

Jak widać, dodałem pole ID do tej jednostki (db users_roles stół też), więc nie jest to świetne rozwiązanie.

//User.js 
module.exports = { 
    tableName: 'users', 
    autoPK: false, 
    attributes: { 
     id: { 
      type: 'integer', 
      primaryKey: true, 
      autoIncrement: true, 
      unique: true, 
     }, 
     name: { 
      type: 'string' 
     }, 
     policies: { 
      collection: 'policy', 
      via: 'user' 
     } 
    } 
} 

i rola jednostki:

//Role.js 
module.exports = { 
    tableName: 'roles', 
    autoPK: false, 
    attributes: { 
     id: { 
      type: 'integer', 
      primaryKey: true, 
      autoIncrement: true, 
     }, 
     alias: { 
      type: 'string', 
      required: true, 
      unique: true, 
     }, 
     policies: { 
      collection: 'policy', 
      via: 'role' 
     } 
    } 
} 

ten sposób uzyskać wszystkie role dla określonego user_id:

... 
id = req.session.me.id; //user_id here 
Policy.get(id, 'role', function(err, roles) { 
    var isAdmin = false; 
    roles.forEach(function(role) { 
     isAdmin |= (role.id === 1); 
    }); 
    if (isAdmin) { 
     next(null); 
     return; 
    } else { 
     return res.redirect('/login'); 
    }   
}); 
... 

Może to być przydatne dla kogoś =)

+0

prawie 2 lata później To było dla mnie przydatne! Dzięki! –