2010-11-25 8 views
1

J'ai donc récemment créé une relation HABTM entre deux modèles (projet & utilisateur).Comment puis-je référencer des données dans une table HABTM sans modèle dans Rails 3?

Avant, j'avais une colonne user_id dans ma table de projet - qui agissait comme une clé étrangère. Maintenant, il y a une table entière qui fait cela.

Mais comment puis-je référencer des projets qui ont un id_utilisateur spécifique & project_id?

Par exemple, je l'habitude d'avoir une section de mon avis qui ressemblait à ceci:

<div class="field"> 
     <%= f.label :project_id %><br /> 
     <%= collection_select(:stage, :project_id, Project.where(:user_id => current_user), :id, :name) %> 
     <br /> 
    </div> 

Mais comment puis-je maintenant tirer les mêmes informations de la db, sans modèle pour la table HABTM? La nouvelle table s'appelle 'projects_users'.

Mon modèle projets ressemble à ceci:

# == Schema Information 
# Schema version: 20101125223049 
# 
# Table name: projects 
# 
# id   :integer   not null, primary key 
# name  :string(255) 
# description :string(255) 
# notified :boolean 
# created_at :datetime 
# updated_at :datetime 
# 

class Project < ActiveRecord::Base 

    has_and_belongs_to_many :users 
    has_many :stages, :dependent => :destroy 
    has_many :uploads 
    has_many :comments 

    #before_validation { |project| project.user = Authorization.current_user unless project.user } 

end 

Mon modèle utilisateur ressemble à ceci:

# == Schema Information 
# Schema version: 20101124095341 
# 
# Table name: users 
# 
# id     :integer   not null, primary key 
# email    :string(255)  default(""), not null 
# encrypted_password :string(128)  default(""), not null 
# password_salt  :string(255)  default(""), not null 
# reset_password_token :string(255) 
# remember_token  :string(255) 
# remember_created_at :datetime 
# sign_in_count  :integer   default(0) 
# current_sign_in_at :datetime 
# last_sign_in_at  :datetime 
# current_sign_in_ip :string(255) 
# last_sign_in_ip  :string(255) 
# created_at   :datetime 
# updated_at   :datetime 
# username    :string(255) 
# role     :string(255) 
# 

class User < ActiveRecord::Base 
    # Include default devise modules. Others available are: 
    # :token_authenticatable, :confirmable, and :lockable 
    devise :database_authenticatable, :registerable, :timeoutable, 
     :recoverable, :rememberable, :trackable, :validatable 

    # Setup accessible (or protected) attributes for your model 
    attr_accessible :email, :password, :password_confirmation, :remember_me 

    has_and_belongs_to_many :projects 
    has_many :stages 
    has_many :uploads 
    has_many :comments 
    has_many :assignments 
    has_many :roles, :through => :assignments 

    def role_symbols 
    roles.map do |role| 
     role.name.underscore.to_sym 
    end 
    end 
end 

En aparté ... Comment puis-je modifier cette table de la console rails - sans un modèle?

Merci.

Répondre

4

Je ne suis pas sûr que je comprends parfaitement votre question, mais Project.where(:user_id => current_user) deviendrais current_user.projects

Et pour ajouter un utilisateur avec id 1 du projet avec id 3 que vous feriez

Project.find(3).users << User.find(1) 

Est-ce ce que vous avez essayé de faire?

+0

en passant à current_user.projects travaillé. Thnx. En ce qui concerne la deuxième partie, est-ce supposé b sur la console? Si oui, ne fonctionne pas. – marcamillion

+1

Oui, vous devez utiliser la deuxième partie de la console. Ça devrait marcher. Êtes-vous sûr d'avoir des instances avec les identifiants que vous utilisez? Essayez ceci à la place: Project.first.users << User.first –

+0

Cela a fonctionné. Où puis-je lire plus à ce sujet? Par exemple, comment puis-je voir toutes les entrées de la table projects_users à partir de la console? – marcamillion

5

Je pense que cela fonctionnera pour vous. Fondamentalement, vous saisissez tous les projets pour un certain utilisateur et ensuite le réduire par project_id.

user_id = 3 #example 
project_id = 2 #example 
User.find(user_id).projects.find(project_id) 

Si vous souhaitez modifier manuellement la table de jointure, vous pouvez utiliser directement les relations.

project = Project.create 
user = User.first 

#add a new row to the join table for the user_id,project_id 
user.projects << project 

#delete all records from the join table referencing this user. 
user.projects = [] 
+0

Lorsque j'exécute 'User.find (user_id) .projects.find (project_id)' c'est le message d'erreur que je reçois: 'variable locale non définie ou méthode' user_id 'pour # <# : 0x00000101e3e8e0> ' – marcamillion

+0

Oui, user_id est supposé être une variable contenant l'id_utilisateur que vous voulez. Je vais mettre à jour la réponse. – rwilliams

+0

Le problème est que j'en ai besoin pour détecter automatiquement le projet courant de l'utilisateur + courant. – marcamillion

Questions connexes