我可以在直通关系中对外键执行`has_many through`吗?

时间:2015-12-04 09:42:53

标签: ruby-on-rails ruby-on-rails-4 associations

我有三个模型 - User, Membership, Connection,它们看起来像这样:

class User < ActiveRecord::Base
  has_many :memberships, dependent: :destroy
end

class Membership < ActiveRecord::Base
  belongs_to :inviter, class_name: "User", foreign_key: "user_id"
  belongs_to :invited, class_name: "User", foreign_key: "invited_id"
  has_many :connections, dependent: :destroy
end

class Connection < ActiveRecord::Base
  belongs_to :inviter_membership, class_name: "Membership", foreign_key: "membership_id"
  belongs_to :invited_membership, class_name: "Membership", foreign_key: "invited_membership_id"
end

但是......我想要做的是设置从userconnections的直接连接。所以,理想情况下,我希望能够user.invited_connectionsuser.inviter_connections,并且它们会对应正确的连接。

即。 user.invited_connections将对应membership.user_id == current_user.id的连接(但请记住,它是与该user_id关联的与该成员资格记录关联的连接...而不仅仅是与user_id相关联的成员资格package features.dataManagement.entity.table.ui; import java.util.ArrayList; import java.util.List; import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import features.dataManagement.entity.table.edit.StringEditingSupport; import features.dataManagement.entity.table.model.RowStringContentProvider; import features.dataManagement.entity.table.model.RowStringModel; public class CompositeTableViewer extends Composite { private TableViewer tableViewer; private List<String> columnNames; private List<RowStringModel> modelList; private Button addButton; public CompositeTableViewer(Composite parent, int style, List<String> columnNames, boolean rowAddable) { this(parent, style, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER, columnNames, rowAddable); } public CompositeTableViewer(Composite parent, int style, int tableViewerStyle, List<String> columnNames, boolean rowAddable) { super(parent, style); modelList = new ArrayList<RowStringModel>(); this.columnNames = columnNames; GridLayout layout = new GridLayout(3, false); layout.marginWidth = 4; this.setLayout(layout); Composite tableComposite = new Composite(this, SWT.NONE); // set 3 columns for the buttons tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); setTableViewer(new TableViewer(tableComposite, tableViewerStyle)); TableViewerColumn tableViewerColumn = createColumn(tableComposite, tableViewer, 0); tableViewerColumn.setEditingSupport(new StringEditingSupport(tableViewer)); TableColumnLayout tableColumnLayout = new TableColumnLayout(); tableColumnLayout.setColumnData(tableViewerColumn.getColumn(), new ColumnWeightData(1, 100, true)); tableComposite.setLayout(tableColumnLayout); tableViewer.setContentProvider(new RowStringContentProvider(tableViewer, modelList)); final Table table = tableViewer.getTable(); table.setLinesVisible(true); createButtons(this, rowAddable); } /* * this is specific to my project you can directly use a * List<RowStringModel> modelList */ public void setInput(List<Object> dataList) { List<RowStringModel> dataStringList = new ArrayList<RowStringModel>(); for (Object str : dataList) { if (str instanceof String) dataStringList.add(new RowStringModel((String) str)); } modelList.addAll(dataStringList); this.tableViewer.setInput(modelList); } /* * this is specific to my project you can directly use a * List<RowStringModel> modelList */ public List<Object> getInput() { List<Object> objectsInGui = new ArrayList<Object>(); for (RowStringModel rowStr : modelList) { objectsInGui.add(rowStr.getContent()); } return objectsInGui; } public void addButtonEnable(boolean enabled) { this.addButton.setEnabled(enabled); } // create the columns for the table private TableViewerColumn createColumn(final Composite parent, final TableViewer viewer, int colNumber) { TableViewerColumn col = createTableViewerColumn(this.columnNames.get(colNumber), colNumber); col.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { RowStringModel rsm = (RowStringModel) element; return rsm.getContent(); } /* slight difference for the actual lines */ @Override public Color getBackground(final Object element) { if (element instanceof RowStringModel) { return new Color(Display.getDefault(), 245, 255, 250); } return super.getBackground(element); } }); return col; } private TableViewerColumn createTableViewerColumn(String title, final int colNumber) { final TableViewerColumn viewerColumn = new TableViewerColumn(tableViewer, SWT.NONE); final TableColumn column = viewerColumn.getColumn(); column.setText(title); column.setResizable(true); column.setMoveable(true); return viewerColumn; } /** * Add the "Add" and "Delete" buttons * * @param parent * the parent composite */ private void createButtons(Composite parent, boolean rowAddable) { // Create and configure the "Add" button this.addButton = new Button(parent, SWT.PUSH | SWT.CENTER); this.addButton.setText("Add"); GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); gridData.widthHint = 80; gridData.horizontalSpan = 1; this.addButton.setLayoutData(gridData); this.addButton.setEnabled(rowAddable); this.addButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { modelList.add(new RowStringModel("")); tableViewer.refresh(); CompositeTableViewer.this.setFocus(); int selection = CompositeTableViewer.this.tableViewer.getTable().getItemCount(); CompositeTableViewer.this.tableViewer.setSelection(new StructuredSelection(tableViewer.getElementAt(selection - 1)), true); } }); // Create and configure the "Delete" button Button delete = new Button(parent, SWT.PUSH | SWT.CENTER); delete.setText("Delete"); gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); gridData.widthHint = 80; delete.setLayoutData(gridData); delete.addSelectionListener(new SelectionAdapter() { // Remove the selection and refresh the view public void widgetSelected(SelectionEvent e) { Object[] dataTable = (Object[]) ((IStructuredSelection) tableViewer.getSelection()).toArray(); if (dataTable != null) { for (Object data : dataTable) { modelList.remove(data); } tableViewer.refresh(); } } }); } public TableViewer getTableViewer() { return tableViewer; } public void setTableViewer(TableViewer tableViewer) { this.tableViewer = tableViewer; } public List<String> getColumnNames() { return columnNames; } public void setColumnNames(List<String> columnNames) { this.columnNames = columnNames; } }

这可能吗?

1 个答案:

答案 0 :(得分:2)

您可以尝试以下方式:

has_many :invited_connections, through: :memberships, source: :invited_membership
has_many :inviter_connections, through: :memberships, source: :inviter_membership

干杯!