Как получить промежуточный объект при использовании функции объекта коллекции в отношениях has_many:through

После определения отношения has_many :through,

@user = User.New(:name=>"Bob")
@project = Project.New( :name=>"Market Survey")
@user.projects << @project

Есть ли простой способ получить новый промежуточный объект, который он создает? например, в приведенном выше примере, если промежуточная таблица является «членством», я мог бы использовать:

@membership = @user.projects << @project

У меня такое чувство, что должен быть лучший способ сделать это, чем то, что мы делаем все время, т.е.

@membership = Membership.where(:user_id=>x , :project_id=>y).first

person Zuhaib Ali    schedule 13.11.2012    source источник


Ответы (3)


Я не знаю никакого «волшебного» способа сделать это. Если вы ищете что-то, что читается лучше, чем то, что вы сделали до сих пор, лучшее, что я могу придумать, это сделать что-то вроде этого:

class User < ActiveRecord::Base
  # ... other active record stuff here.

  def membership_for(project)
    memberships.where(:project_id => project.id).first
  end
end

# Somewhere else...
@user = User.new(:name=>"Bob")
@project = Project.new(:name=>"Market Survey")
@user.projects << @project
@user.save!

membership = @user.membership_for(@project)

Не идеально и требует дополнительного кода, но он читается лучше, чем ваш текущий код, и это имеет большое значение в Ruby.

person Paul Russell    schedule 14.11.2012
comment
Увы! В рельсах, где все волшебно, мне было трудно поверить, что мне нужно было использовать дополнительную команду (то есть дополнительный запрос), чтобы сделать это обычное и простое. - person Zuhaib Ali; 14.11.2012

Вы можете сделать что-то вроде:

@membership = @user.members.find_by_project_id(@project.id)

не уверен, что это проще/лучше, чем то, что вы делаете.

person Ian Armit    schedule 13.11.2012

Я не уверен, понимаю ли я ваш вопрос. Если у одного пользователя много проектов, я думаю, вы можете использовать это:

@user = User.create(:name=>"Bob")

# Create project and membership with user_id of @user same time, return project.
@project = @user.projects.create(:name=>"Market Survey")

Если вы хотите найти членство, я думаю, что есть другой способ:

@membership = Membership.find(:first, conditions: { user_id: x, project_id: y })
person Thanh    schedule 14.11.2012