本文翻译自CATIAV5help文档,加上部分自己的理解,从今天起翻译技术文档,保持周更三篇到五篇.
本文介绍了被CATIA V5支持的一般情况的拓扑概念.
定义拓扑结构后,描述基本的元素实体(单元,域,体),然后介绍和说明非流形(non-mainfold)拓扑.汇总表向读者可视化了这些概念之间的联系,
译者注:这个流程和我们在零件设计的过程中息息相关.稍后会贴出一段代码来说明这段流程. .
拓扑允许通过对象的详细的边界信息和相互间的联系信息来(表示对象)建模,

.1.壳对象由一个拓扑学中的面(F)的二维实体构成
.2.面F被四个相连的一维边界限制,称这个边界为(E!,E2,E3,E4
)每条边(例如E1)是一条几何曲线©限制,位于曲面上,以两个顶点(V1,V2为界)
.3.边缘由他们的顶点连接,以限制面
(规整的)对象称为流形(mainfold)而呈现(头发"hair",鳞片"scale")状称为非流形.
,非流形的使用对于简化物体的表达非常有帮助,一个实体的加强筋就可以表示为一个二维的(鳞片"scale")

在这个对象中,加强筋被建模为一个二维的拓扑元素,但也关联到了3D对象的一个面,这是一个非流形的表面配置
不带面F的对象B是流形即,标准型
详细定义查看本文流形与非;流形的的定义部分.请到目录中查看
CGM(CATIA Geometric Modeler CATIA几何建模器)使用一种细胞混合""的技术,它允许你1.统一处理多维概念 2.表示所有的流形和非流形对象
拓扑管理三种类型的实体
| Cell | 最基本的拓扑对象 |
|---|---|
| domain | 一组连接的单元 |
| body | 要建模的本身 |
单元是基础几何的连接限制。
根据它们所在空间的尺寸,有四种类型的细胞。
| 空间维度 | cell类型 | 与几何的联系 |
|---|---|---|
| 0 | Vertex顶点 | 点Point |
| 1 | Edge边 | 曲线Curve |
| 2 | Face面 | 曲面Surface |
| 3 | volume | 3D空间 |
高维单元受低维单元的限制:体积是 3D 空间受面的限制,面是曲面受边的限制,边是曲线受顶点的限制。

域是一组由维度为 n-1 的单元连接的维度为 n 的单元。一个域可能只包含一个单元格。
域对于完全操纵高维单元的边界很有用。例如,如果一张脸由四个相连的边界定,那么所有这些边都可以方便地分组到一个域中。与单元格一样,域根据其实际包含的内容具有特定的名称。
|
| A … | is a set of … | bounding … |
|---|---|---|
| loop | edges connected by vertices | a face |
| vertex in face | one vertex | a face |
| lump | volumes connected by faces | the 3D space |
| shell | faces connected by edges | the 3D space or a volume |
| wire | edges connected by vertices | the 3D Space |
| in | one vertex the 3D Space or a volume |
体积中的块、壳、线和顶点是 3D 实体的边界。面中的环和顶点是二维实体的边界。没有域与边的边界(一维实体)相关联:顶点直接限制边,因为这样的域不会为模型带来任何附加值。


立方体 C3 和 C4 只有边 E 相同:它们必须放入不同的块中,因为块是由面连接的一组体积。每个块是非流形全局对象的流形组件。
一个体是一组不一定相连的域(没有任何尺寸的共同边界)。体必须满足以下属性。

如果面 F1 和 F2(分别位于面 F1 和 F2 上)是物体 B 的单元,则位于 S1
body只引用域,即使域中只有一个单元格。请参见下一节的示例:主体仅包含一个体积,但它通过块域包含它。和 S2 交点上的边 E 必须存在并且也是 B 的单元。
此示例显示了将表示具有腔的长方体的主体分解为单元和域。为了描述清晰,有些关系没有显示出来。

CGM 允许您创建和使用流形和非流形实体。从数学上讲,N 流形对象是一组点,其邻域由 N 维碗表示。取一个块域(分别是外壳,循环)。如果对于这个域的每个点,存在一个域的邻域仅相当于一个球体(分别是圆盘、段),则块(分别是壳、环)是 3D(分别是 2D、1D)-多方面的。否则,它是非流形的。
下图显示了流形和非流形对象的示例。有非流形的地方被突出显示。实体可以是:
|
| 流形 | 非流形 | |
|---|---|---|
| 1D_ | ![]() | |
| 2D_ | ![]() |
|–|–|
| 3D_ | 
|
非流形拓扑提供了几个好处:

当一个物体包含非连接单元或非流形配置时,有必要将其划分为多个流形域。以下步骤确保将主体唯一分解为域:




大多数操作可以在非流形体上执行,但不是全部。趋势是允许用户检查他是否接受生成非流形结果。例如,您将无法挤出或填充具有封闭部分但具有自由边缘的轮廓,除非您取消选中“歧管”复选框,否则您将无法将非歧管主体连接到另一个body。
请注意,CGM 服务允许您创建非流形实体,而 CATIA 工作台通常会将创建的实体“分解”为适当的域。这样,生成的实体不是流形的,但包含易于操作的子元素。下面的例子说明了这种策略。
通过组装三条并发的线(使用CATTopWire然后CATHybAssemble)创建一个三边体(见右图)。这个体是由四个顶点和三条边组成的。它显然是非模态的。你可以通过使用CATBody::GetCellsHighestDimension方法来检查这一点。

如果您尝试使用 Join 交互式命令将突出显示的主体(一条线)与三边主体连接,您将收到以下消息:
“Update error: Non Manifold Body”.
现在,如果您尝试移除使生成的主体非流形的边缘(使用“连接定义”对话框中的“要移除的子元素”选项卡),您将收到以下消息:
“Bad topology”.
此消息告诉您要删除的子元素未完全包含在域中。实际上,它与另外两条线共享一个顶点。你不能在你的操作中走得更远,你必须重建初始主体以使其成为歧管或将其划分为如上所述的多个域。在这种情况下,最好的方法是将主体分成三个不共享任何顶点的单边线。
给定一个看起来像上面的三边流形体,但由三根线和六个顶点组成,如果您尝试将突出显示的主体(一条线)与三边主体连接,您还将收到以下消息:
“Update error: Non Manifold Body”.

但是现在,如果您尝试删除使生成的实体不流形的边(使用“连接定义”对话框中的“要删除的子元素”选项卡),CATIA 将删除它并且连接操作将完成。
当您尝试使用 Sketcher 命令创建非流形体时,创建的体将是非流形体,但实际上它会自动划分为流形域,以便进一步操作需要删除不合适的元素将变得更容易. Sketcher 坚持这一策略。
主体是一组域,其中包含连接的单元格,这些单元格以较低维度的域为界,…
建立规则以提供body的独特分解。
下图总结了域和单元之间的关系。箭头 domain->cell 表示关系“由…组成”。箭头单元格-> 域表示关系“有界”。

//引用和界面搭建部分省略
//创建新的Part文件
CATDocument * pDoc = NULL;
HRESULT rc = CATDocumentServices::New("Part", pDoc);
if ( FAILED(rc) || NULL == pDoc ) return ;
//新Part文件初始化
CATInit * pInit = NULL;
rc = pDoc->QueryInterface(IID_CATInit, (void**)&pInit);
if (FAILED(rc)|| NULL == pInit ) return ;
pInit->Init(TRUE);
//获取结构container
CATIContainerOfDocument_var spNewDocContainer = pDoc;
CATIContainer *piNewContainer = NULL;
rc = spNewDocContainer->GetSpecContainer(piNewContainer);
if (FAILED(rc) || piNewContainer == NULL) return ;
CATIPrtContainer* pPrtCon = NULL;
rc= piNewContainer->QueryInterface( IID_CATIPrtContainer,(void **)&pPrtCon);
if (FAILED(rc) || pPrtCon == NULL) return ;
//设置草图工厂,设置轴系工厂
CATIPrtContainer* pIPrtContOnDocument = pPrtCon;
CATIMf3DAxisSystemFactory * pIMf3DAxisSystemFactoryOnFeatCont = NULL ;
rc=pIPrtContOnDocument->QueryInterface(IID_CATIMf3DAxisSystemFactory,
(void **) & pIMf3DAxisSystemFactoryOnFeatCont);
CATISketchFactory * pISketchFactoryOnFeatCont = NULL ;
rc=pIPrtContOnDocument->QueryInterface(IID_CATISketchFactory,
(void **) & pISketchFactoryOnFeatCont);
//创建轴系
CATMathPoint Origin (100.0,.0,.0);
CATMathVector Xdir (1.0,0.0,.0);
CATMathVector Ydir (0.0,0.0,1.0);
CATIMf3DAxisSystem_var NewAxisSystem ;
rc = pIMf3DAxisSystemFactoryOnFeatCont->CreateAxisSystem(Origin,Xdir,Ydir,NewAxisSystem);
//添加轴系到视图中
CATISpecObject * pSpecObjectOnAxisSystem = NULL ;
rc=NewAxisSystem->QueryInterface(IID_CATISpecObject,(void **)&pSpecObjectOnAxisSystem);
CATTry pSpecObjectOnAxisSystem->Update();
CATCatch(CATError,error)
{
Flush(error);
return ;
}
CATEndTry
//获取轴系的xy平面
CATIBRepAccess_var PlaneBRep ;
rc = NewAxisSystem->GetPlaneBRepAccess(CATAxisSystemZNumber,PlaneBRep);
//Brep对象特征化
CATIFeaturize * pIFeaturizeOnPlane = NULL ;
rc = PlaneBRep->QueryInterface(IID_CATIFeaturize,(void **) &pIFeaturizeOnPlane);
CATISpecObject_var MFPlane = pIFeaturizeOnPlane->FeaturizeF();
//创建草图
CATISpecObject_var NewSketch = pISketchFactoryOnFeatCont->CreateSketch(MFPlane);
//启动草图编辑器
CATISketch_var spSketch(NewSketch); if ( NULL_var == spSketch ) return ;
spSketch->OpenEdition();
//开始草图绘图
CATI2DWFFactory_var sketch2DFactory(spSketch); // 获取 2D工厂来创建图形
CATI2DPoint_var spPt_bottom_left, spPt_bottom_right, spPt_top_right, spPt_top_left;
CATI2DLine_var spLine1, spLine2, spLine3, spLine4;
double pt_bottom_left[2] = {10., 10.};
double pt_bottom_right[2] = {50., 10.};
double pt_top_right[2] = {50., 50.};
double pt_top_left[2] = {10., 50.};
spPt_bottom_left = sketch2DFactory->CreatePoint(pt_bottom_left);
spPt_bottom_right = sketch2DFactory->CreatePoint(pt_bottom_right);
spPt_top_right = sketch2DFactory->CreatePoint(pt_top_right);
spPt_top_left = sketch2DFactory->CreatePoint(pt_top_left);
spLine1 = sketch2DFactory->CreateLine(pt_bottom_left,pt_bottom_right);
spLine2 = sketch2DFactory->CreateLine(pt_bottom_right,pt_top_right);
spLine3 = sketch2DFactory->CreateLine(pt_top_right,pt_top_left);
spLine4 = sketch2DFactory->CreateLine(pt_top_left,pt_bottom_left);
// 将线连接起来
CATI2DCurve_var spCurve1 (spLine1);
CATI2DCurve_var spCurve2 (spLine2);
CATI2DCurve_var spCurve3 (spLine3);
CATI2DCurve_var spCurve4 (spLine4);
spCurve1->SetStartPoint(spPt_bottom_left);
spCurve1->SetEndPoint(spPt_bottom_right);
spCurve2->SetStartPoint(spPt_bottom_right);
spCurve2->SetEndPoint(spPt_top_right);
spCurve3->SetStartPoint(spPt_top_right);
spCurve3->SetEndPoint(spPt_top_left);
spCurve4->SetStartPoint(spPt_top_left);
spCurve4->SetEndPoint(spPt_bottom_left);
//设置草图约束
CATI2DConstraintFactory_var spConstraint2DFactory(spSketch);
spConstraint2DFactory->CreateConstraint( spLine1, NULL, NULL, NULL, NULL, NULL, NULL,
Cst2DType_Horizontal, 0, 0 );//水平约束
spConstraint2DFactory->CreateConstraint( spLine2, NULL, NULL, NULL, NULL, NULL, NULL,
Cst2DType_Vertical, 0, 0 ); //垂直约束
spConstraint2DFactory->CreateConstraint( spLine3, NULL, NULL, NULL, NULL, NULL, NULL,
Cst2DType_Horizontal, 0, 0 ); //水平约束
spConstraint2DFactory->CreateConstraint( spLine4, NULL, NULL, NULL, NULL, NULL, NULL,
Cst2DType_Vertical, 0, 0 ); //垂直约束
spConstraint2DFactory->CreateConstraint( spLine2, NULL, NULL, NULL, NULL, NULL, NULL,
Cst2DType_Length, 0, 0 ); //长度约束
spConstraint2DFactory->CreateConstraint( spLine2, NULL, spLine4, NULL, NULL, NULL, NULL,
Cst2DType_Distance, 0, 0 ); //距离约束
//创建草图修饰——圆倒角
double radius = 10.;
double pt_center[2] = {70., 40.};
CATI2DCurve_var spCurve5 = sketch2DFactory->CreateCorner(spCurve3, spCurve4, pt_center, &radius);
CATI2DTopologicalOperators_var spOperateur = spSketch;
spOperateur->InsertCorner(spCurve5,spLine3,1,spLine4,1);
spConstraint2DFactory->CreateConstraint( spLine3, NULL, spCurve5, NULL, NULL, NULL, NULL,
Cst2DType_Tangent, 0, 0);
spConstraint2DFactory->CreateConstraint( spCurve5, NULL, spLine4, NULL, NULL, NULL, NULL,
Cst2DType_Tangent, 0, 0);
spConstraint2DFactory->CreateConstraint( spCurve5, NULL, NULL, NULL, NULL, NULL, NULL,
Cst2DType_Radius, 0, 1);
//关闭草图编辑器
spSketch->CloseEdition();
//添加草图到视图中
CATISpecObject * pSpecObjectOnSketch = NULL ;
rc=spSketch->QueryInterface(IID_CATISpecObject,(void **)&pSpecObjectOnSketch);
CATTry pSpecObjectOnSketch->Update();
CATCatch(CATError,error)
{
Flush(error);
return ;
}
CATEndTry
//创建几何特征集
CATIPrtContainer* ipPrtCont = pPrtCon;//结构Container
CATIMechanicalRootFactory *pSetToolFactory=NULL;//设置MechanicalRoot工厂
rc=ipPrtCont->QueryInterface(IID_CATIMechanicalRootFactory,(void **)& pSetToolFactory);
if(FAILED(rc)|| pSetToolFactory ==NULL) return;
CATIPrtPart_var spPart=ipPrtCont->GetPart();
if(spPart==NULL_var) return ;
CATISpecObject_var spPRTTool;
spPRTTool= pSetToolFactory->CreatePRTTool("复制的几何体",spPart);
//复制凸台特征用接口 CATICutAndPastable
if (spSpecObj == NULL_var) return;
//获取特征容器
CATIContainer_var spContainer = spSpecObj->GetFeatContainer();
if (spContainer == NULL_var)return;
//由容器查找到剪切粘贴接口
CATICutAndPastable *pCutAndPastable = NULL;
rc = spContainer->QueryInterface(IID_CATICutAndPastable, (void **)&pCutAndPastable);
if (FAILED(rc) || pCutAndPastable==NULL)return ;
//添加删除元素
CATLISTV(CATBaseUnknown_var) listOfUnknown;
listOfUnknown.Append(spSpecObj);
pCutAndPastable->Paste(listOfUnknown);
//复制凸台特征到 复制的几何体 用接口CATMmrInterPartCopy
CATISpecObject_var SourceToCopy = spSpecObj;
CATISpecObject_var Target = spPRTTool;
//创建CATMmrInterPartCopy类的实例
CATMmrInterPartCopy * ptCATMmrInterPartCopy = new CATMmrInterPartCopy (SourceToCopy, Target) ;
//用SetLinkMode 方法设置复制选项
ptCATMmrInterPartCopy ->SetLinkMode(FALSE);
//采用run()方法执行复制任务
CATUnicodeString ErrorMsg = "" ;
rc = ptCATMmrInterPartCopy ->Run(&ErrorMsg);
//采用GetResult方法获取复制结果。代码如下:
CATISpecObject_var Result;
rc = ptCATMmrInterPartCopy ->GetResult(Result);
//复制结果添加到视图
Result->Update();
//更改实体的颜色属性
CATIMfGeometryAccess *pPadAsGeomAccess = NULL;//定义拓扑几何元素接口
rc= Result->QueryInterface
(IID_CATIMfGeometryAccess, (void**)&pPadAsGeomAccess) ;//获取拓扑几何元素接口
if (FAILED(rc) ) return ;
CATLISTV(CATBaseUnknown_var) PadBReps;
pPadAsGeomAccess->GetBReps(PadBReps);//获取所有的拓扑元素 BRep面
// 6-3 替BRep面 更改颜色
for(int currentBRep=1; currentBRep<=PadBReps.Size(); currentBRep++)
{
CATIVisProperties
*pPadBrepAsGraphics = 0;
const CATBaseUnknown_var& currentPadBRep = PadBReps[currentBRep];
if (NULL_var !=
currentPadBRep)
rc = currentPadBRep->QueryInterface(IID_CATIVisProperties,(void**)&pPadBrepAsGraphics) ;//获取面的属性接口
if ( SUCCEEDED(rc) )
{
int R,G,B;
R=0;
G=200;
B=0;
CATVisPropertiesValues color;//定义颜色属性
color.SetColor(R, G, B); // green
pPadBrepAsGraphics->SetPropertiesAtt(color, CATVPColor, CATVPMesh);//设置颜色属性
pPadBrepAsGraphics->Release();
pPadBrepAsGraphics = NULL ;
}
}
//重命名特征
if ( NULL_var == Result ) return;
CATIAlias* pAlias = NULL;
rc = Result->QueryInterface(IID_CATIAlias, (void**)&pAlias);//获取名称接口
if ( SUCCEEDED(rc) )
{
pAlias->SetAlias("复制的块");//设置名称
pAlias->Release();
pAlias = NULL;
}
//更改Part特征名称为NewPart
CATIAPartDocument* pCATIAPrtDoc = NULL;
CATIAProductDocument * pCATIAPrdtDoc = NULL;
rc = pDoc->QueryInterface(IID_CATIAPartDocument, (void**)&pCATIAPrtDoc);
rc = pDoc->QueryInterface( IID_CATIAProductDocument, (void**)&pCATIAPrdtDoc );
if ( NULL == pCATIAPrdtDoc && NULL == pCATIAPrtDoc ) return;
CATIAProduct* pCATIAPrtRoot = NULL;
if ( NULL != pCATIAPrtDoc )
{
pCATIAPrtDoc->get_Product(pCATIAPrtRoot);
}
else if ( NULL != pCATIAPrdtDoc )
{
pCATIAPrdtDoc->get_Product(pCATIAPrtRoot);
}
if (NULL == pCATIAPrtRoot )return;
CATUnicodeString PartNumber ="NewPart";
CATBSTR bstr;
PartNumber.ConvertToBSTR(&bstr);
pCATIAPrtRoot->put_PartNumber(bstr);
pCATIAPrtRoot->Update();
CATBSTR newBstr;
pCATIAPrtRoot->get_PartNumber(newBstr);
CATUnicodeString s;
s.BuildFromBSTR(newBstr);
if ( NULL != pCATIAPrtDoc )
{
pCATIAPrtDoc->Release(); pCATIAPrtDoc = NULL;
}
if ( NULL != pCATIAPrdtDoc )
{
pCATIAPrdtDoc->Release(); pCATIAPrdtDoc = NULL;
}
//设置草图为显示状态
CATIVisProperties *pVisProperties = NULL;
rc = pSpecObjectOnSketch->QueryInterface(IID_CATIVisProperties,(void**)&pVisProperties);
if( SUCCEEDED(rc) && pVisProperties!=NULL)
{
CATVisPropertiesValues MyProp;
pVisProperties->GetPropertiesAtt(MyProp, CATVPShow);
MyProp.SetShowAttr(CATShowAttr);
pVisProperties -> SetPropertiesAtt(MyProp,CATVPShow ,CATVPGlobalType);// CATVPShow CATVPGlobalType
pVisProperties -> Release();
pVisProperties = NULL ;
}
pSpecObjectOnSketch->Update();
//设置文件路径
CATUnicodeString DocTitle="NewPart";
CATUnicodeString DocName="NewPart.CATPart";
CATUnicodeString DocPath="D:\\";
CATDocumentServices::SaveAsNew(*pDoc, DocPath+ DocName);//
五月二十九日初稿,
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只
我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA