odoo-14.0.post20221212.tar
base_user_role-12.0.2.1.2.zip
下载地址:
https://apps.odoo.com/apps/modules/12.0/base_user_role/
为了更好的熟悉权限,我们先来了解下用户,odoo中的用户分为三类:
Internal User): 企业内部的用户,拥有对系统内部的访问权限,也就是说有odoo后端的访问权限。Portal): 非企业内部用户,通常为业务合作伙伴用户,拥有有限的资源访问权限。Public): 面向公众的权限,可以理解为游客权限。提示:管理员登录系统,激活开发者模式,即可在设置-用户详情页对用户类型进行编辑(Settings -> Users & Companies -> Users)
以上三类用户的信息都存在res_user与res_partner表中,那么在odoo中如何区分用户类型以及如何做权限控制的呢?
为了解决上述问题,odoo采用了用户组机制。将用户划分为不同的组(一个用户可以归属多个用户组,一个用户组也可以拥有多个用户),然后给组分配权限,从而实现用户权限的管控及用户类型识别。
以上三种用户分别归属以下用户组:
base.group_userbase.group_portalbase.group_publicodoo也支持自定义用户组(Settings -> Users & Companies -> Groups),并为用户分配不同的用户组,及设置相关权限(菜单权限,视图权限,访问权限,记录规则)
此外,为了更方便的管理用户组,odoo还支持对用户组(group)进行分类:将多个用户组划分为一个用户组分类(category)。
示例:xml数据文件的方式定义菜单权限用户组
<odoo>
<data noupdate="1">
<record id="estate_property_menu_groups" model="ir.module.category"><!-- id:供代码或者xml中引用,model:odoo的category模型-->
<field name="name">[房地产]模块菜单权限</field><!--用户组分类名称-->
<field name="sequence">1</field><!--组分类显示顺序、优先级-->
</record>
<!--########################
[房地产]模块菜单
########################-->
<record id="group_estate_property_root_menu" model="res.groups">
<field name="name">Real Estate</field><!--用户组名称,阐明组的角色/目的-->
<field name="category_id" ref="estate_property_menu_groups"/><!--指定用户组所属组分类-->
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/><!--定义用户组继承自哪些组,也就是说该用户组也拥有这些继承组的权限-->
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/><!--为用户组添加用户 base.user_root root用户 -->
</record>
</data>
</odoo>
说明:
noupdate:如果数据文件的内容预期只应用一次(只加载一次,安装或者更新模块时),则可以将noupdate设置为1。如果文件中的部分数据需要应用一次,则可以将文件的这部分放在<data-noupdate="1">中,如下:
<odoo>
<data noupdate="1">
<!-- Only loaded when installing the module (odoo-bin -i module) -->
<operation/>
</data>
<!-- (Re)Loaded at install and update (odoo-bin -i/-u) -->
<operation/>
</odoo>
base.user_admin :admin用户(ID为2的用户,用户数据定义在odoo\addons\base\data\res_users_data.xml中
base.user_root: __system__用户(ID为1的用户,technical admin )
category定义相关数据存储在ir_module_category表中
添加的group,可以在Settings -> Users & Groups -> Groups界面看到,组定义相关数据存储在res_groups表中
(0, 0, values) 从提供的valueS字典创建新记录,形如(0, 0, {'author': user_root.id, 'body': 'one'})。(2, ID, values) 使用values字典中的值更新id值=ID的现有记录(2, ID) 删除id=ID这条记录(调用unlink方法,删除数据及整个主从数据链接关系)(3, ID) 删除主从数据的链接关系但是不删除这个记录(4, ID) 为id=ID的数据添加主从链接关系(5) 去除所有的链接关系,也就是循环所有的从数据且调用(3,ID)(6, 0, [IDs]) 用IDs中的记录替换原来链接的记录(相当于先执行(5)再循环执行(4, ID))拓展:
odoo中有个特殊的组base.group_no_one,需要开启Debug模式才可获取该组权限。可以利用该特性实现隐藏对象需求,比如针对一些常规下不需要显示的特殊字段,为其设置属性groups = "base.group_no_one",可以实现在非Debug模式下隐藏字段在视图中的显示。
estate/security/security_estate_property_menu_groups.xml
<odoo>
<data noupdate="1">
<record id="estate_property_menu_groups" model="ir.module.category">
<field name="name">[房地产]模块菜单权限</field>
<field name="sequence">1</field>
</record>
<!--########################
[房地产]模块菜单
########################-->
<record id="group_estate_property_root_menu" model="res.groups">
<field name="name">Real Estate</field>
<field name="category_id" ref="estate_property_menu_groups"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
<record id="group_estate_property_advertisements_menu" model="res.groups">
<field name="name">Real Estate -> Advertisements</field>
<field name="category_id" ref="estate_property_menu_groups"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
<record id="group_estate_property_advertisements_properties_menu" model="res.groups">
<field name="name">Real Estate -> Advertisements -> Properties</field>
<field name="category_id" ref="estate_property_menu_groups"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
</data>
</odoo>
estate/__manifest__.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
{
'name': 'estate',
'depends': ['base'],
'data':[
'security/security_estate_property_menu_groups.xml',
//...略
]
}
views/estate_menus.xml
<?xml version="1.0"?>
<odoo>
<menuitem id="test_menu_root" name="Real Estate" web_icon="estate,static/img/icon.png"
groups="group_estate_property_root_menu">
<menuitem id="test_first_level_menu" name="Advertisements" groups="group_estate_property_advertisements_menu">
<menuitem id="estate_property_menu_action" action="link_estate_property_action" groups="group_estate_property_advertisements_properties_menu"/>
<!--略-->
</menuitem>
<!--略-->
</menuitem>
</odoo>
查看效果


注意:
实践时发现,通过界面点击,访问一些菜单界面时,会在菜单访问URL(参见菜单访问自动生成的URL)中自动添加model,view_type等参数,也就是说会自动访问模块相关模型,如果此时没有对应模型的访问权限(至少需要 read权限),那么即便拥有对应菜单的访问权限,界面上也看不到对应的菜单,笔者尝试过在浏览器中直接通过菜单链接(形如二级导航菜单http://localhost:8888/web#action=85&cids=1&menu_id=127)访问菜单,发现界面上不会显示任何菜单。
菜单访问自动生成的URL
http://localhost:8888/web#action=85&model=estate.property&view_type=kanban&cids=1&menu_id=70
通过上述方式实现的菜单访问权限控制,实际是通过控制是否隐藏菜单实现的,也就说,如果知道未授权菜单ID,还是可以通过菜单ID拼接菜单URL进行未授权访问。
当模型中没有定义任何访问权限时,odoo会认为没有任何用户可以访问数据,并在日志中打印:
2022-12-14 09:01:38,994 32508 WARNING odoo odoo.modules.loading: The model estate.property has no access rules, consider adding one. E.g. access_estate_property,access_estate_property,model_estate_property,base.group_user,1,0,0,0
访问权限被定义为ir.model.access 模型记录。每个访问权限关联一个模型,一个group(针对全局访问,没有组) 和一系列权限:create, read, write 和unlink(等同于delete)。这些访问权限通常定义在security/ir.model.access.csv文件中。
test.model模型访问权限配置示例
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_test_model,access_test_model,model_test_model,base.group_user,1,0,0,0
id 自定义外部标识,模块中保持唯一,一般命名为 access_模型名称_用户组名称name 自定义ir.model.access的名称,一般命名沿用id取值即可model_id/id 、model_id:id 代指需要应用访问权限的模型。标准格式为 model_<model_name>,其中, <model_name>为模块中_name 替换.为_后的_name 的值group_id/id 、group_id:id 代指需应用访问权限的组,即指定哪个组拥有如下访问权限,如果指定组不是在当前模块中定义的组,需要指定模块名称,形如module_name.groupName。组名一般命名为group_模型名称_权限,形如group_estate_property_read 。如果 group_id为空,则意味着授权给所有用户(非雇员(employees) ,比如 portal 或者public用户).perm_read,perm_write,perm_create,perm_unlink: 分别代表create(创建), read(只读/查询), write (编辑/更新)和unlink(删除)权限,1表示有访问权限,0-表示无权限具体到实际应用时,为了更灵活的权限管理,一般会为模型的增删改查操作分别定义权限。
授权给用户的模型访问权限,可通过点击Settings -> Users & Groups -> Users用户详情页Access Rights按钮查看。
xml数据文件的方式定义房地产模型访问权限
estate/security/security_estate_property_model_groups.xml
<odoo>
<data noupdate="1">
<record id="estate_property_model_groups" model="ir.module.category">
<field name="name">[房地产]模型权限</field>
<field name="sequence">1</field>
</record>
<!--########################
[房地产]模型
########################-->
<!-- [房地产]模型 增删改查 -->
<record id="group_estate_property_read" model="res.groups">
<field name="name">[房地产]模型 只读</field>
<field name="category_id" ref="estate_property_model_groups"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
<record id="group_estate_property_write" model="res.groups">
<field name="name">[房地产]模型 更新</field>
<field name="category_id" ref="estate_property_model_groups"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
<record id="group_estate_property_create" model="res.groups">
<field name="name">[房地产]模型 创建</field>
<field name="category_id" ref="estate_property_model_groups"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
<record id="group_estate_property_delete" model="res.groups">
<field name="name">[房地产]模型 删除</field>
<field name="category_id" ref="estate_property_model_groups"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
</data>
</odoo>
estate/security/ir.model.access.csv
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_estate_property_group_estate_property_read,access_estate_property_group_estate_property_read,model_estate_property,group_estate_property_read,1,0,0,0
access_estate_property_group_estate_property_write,access_estate_property_group_estate_property_write,model_estate_property,group_estate_property_write,1,1,0,0
access_estate_property_group_estate_property_create,access_estate_property_group_estate_property_create,model_estate_property,group_estate_property_create,1,0,1,0
access_estate_property_group_estate_property_delete,access_estate_property_group_estate_property_delete,model_estate_property,group_estate_property_delete,1,0,0,1
estate/__manifest__.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
{
'name': 'estate',
'depends': ['base'],
'data':[
'security/security_estate_property_menu_groups.xml',
'security/security_estate_property_model_groups.xml',
'security/ir.model.access.csv',
//...略
]
}
打开用户编辑界面

记录规则是允许某个操作必须满足的条件。记录规则按照访问权限逐条记录评估。
默认允许的记录规则:如果授予模型访问权限(Access Rights),并且没有规则适用于用户的操作和模型,则授予访问权限
记录规则保存在ir.rule模型表里,我们通过管理ir_rule表中的记录,即可控制记录的访问权限
示例:xml数据文件的方式定义房地产模型记录访问规则
<odoo>
<data noupdate="0">
<!--########################
[房地产]模型记录规则
########################-->
<record id="estate_property_record_read_rule" model="ir.rule"><!--id:外部规则id,供代码或者xml中引用 -->
<field name="name">[房地产]模型记录规则</field>
<field name="model_id" ref="model_estate_property"/>
<field name="domain_force">[('create_uid', '=', user.id)]</field><!--仅显示用户自己创建的记录-->
<field name="groups" eval="[(4, ref('group_estate_property_record_read'))]"/>
<!--操作权限(仅作用于经domain_force滤后的记录)-->
<field name="perm_read" eval="1"/>
<field name="perm_write" eval="1"/>
<field name="perm_create" eval="1"/>
<field name="perm_unlink" eval="1"/>
</record>
</data>
</odoo>
name
规则名称
model_id
需要应用规则的模型,标准格式为 model_<model_name>,其中, <model_name>为模块中_name 替换.为_后值
groups
指定规则需要作用、不作用于哪些组(res.groups)。可以指定多个组。如果未指定组,规则为gobal规则。规则与组的关联关系存在rule_group_rel表中
global
根据“groups”计算,提供了对规则是否全局状态的轻松访问。eval="True"、eval="1"则表示全局规则,eval="False"、eval="0"则表示非全局规则
domain_force
指定为 domain的谓词,如果该domain与记录匹配,则规则允许所选操作,否则禁止。可以简单的理解为指定过滤条件,用户只能访问符合本过滤条件的记录,配置为 [(1,'=',1)]则表示匹配所有记录。domain是一个可以使用以下变量的python表达式:
time
Python的 time 模块
user
以单例记录集(singleton recordset)表示的当前用户
company_id
当前用户,当前所选的公司的公司id(非记录集)。
company_ids
当前用户可以访问的公司ID列表(非记录集)。 查看Security rules 获取更多详细信息。
官方文档:
The
perm_methodhave completely different semantics than forir.model.access: for rules, they specify which operation the rules applies for. If an operation is not selected, then the rule is not checked for it, as if the rule did not exist.All operations are selected by default
译文:
perm_method具有与ir.model.access完全不同的语义:对于规则,它们指定规则需要应用的操作。如果(规则)未选择某个操作,则不会为该操作检查规则,就像该规则不存在一样。规则默认适用所有操作。
笔者实践发现:
perm_method的eval值不能同时为"False"、"0",否则会违反 ir_rule表的检查约束ir_rule_no_access_rights:CHECK (perm_read!=False or perm_write!=False or perm_create!=False or perm_unlink!=False)perm_method设置为eval="True"、eval="1" ,并将规则授权给用户,规则生效,所以我个人理解,目前记录规则,就是用于过滤记录的,通过domain_force控制哪些记录可以显示给用户规则默认适用所有操作。
perm_create
``perm_read`
perm_write
perm_unlink
授权给用户的记录访问规则,可通过点击Settings -> Users & Groups -> Users用户详情页Record Rules按钮查看。
全局规则和组规则在组成和组合方式上存在很大差异:
危险提示
创建多个全局规则是有风险的,因为可能创建不重叠的规则集,这将删除所有访问权限
estate/security/security_estate_property_model_groups.xml,新增group_estate_property_record_query组
<odoo>
<data noupdate="1">
<record id="estate_property_model_groups" model="ir.module.category">
<field name="name">[房地产]模型权限</field>
<field name="sequence">1</field>
</record>
<!--########################
[房地产]模型
########################-->
<!-- [房地产]模型 增删改查 -->
<record id="group_estate_property_read" model="res.groups">
<field name="name">[房地产]模型 只读</field>
<field name="category_id" ref="estate_property_model_groups"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
<record id="group_estate_property_write" model="res.groups">
<field name="name">[房地产]模型 更新</field>
<field name="category_id" ref="estate_property_model_groups"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
<record id="group_estate_property_create" model="res.groups">
<field name="name">[房地产]模型 创建</field>
<field name="category_id" ref="estate_property_model_groups"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
<record id="group_estate_property_delete" model="res.groups">
<field name="name">[房地产]模型 删除</field>
<field name="category_id" ref="estate_property_model_groups"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
</data>
<data noupdate="0">
<!--########################
[房地产]模型记录
########################-->
<record id="group_estate_property_record_query" model="res.groups">
<field name="name">[房地产]模型记录 查询</field>
<field name="category_id" ref="estate_property_model_groups"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
</data>
</odoo>
estate/security/security_estate_property_model_record_rules.xml
<odoo>
<data noupdate="0">
<!--########################
[房地产]模型记录规则
########################-->
<record id="estate_property_record_read_rule" model="ir.rule">
<field name="name">[房地产]模型记录规则</field>
<field name="model_id" ref="model_estate_property"/>
<field name="domain_force">[('create_uid', '=', user.id)]</field>
<field name="groups" eval="[(4, ref('group_estate_property_record_read'))]"/>
<field name="perm_read" eval="1"/>
<field name="perm_write" eval="1"/>
<field name="perm_create" eval="1"/>
<field name="perm_unlink" eval="1"/>
</record>
</data>
</odoo>
estate/__manifest__.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
{
'name': 'estate',
'depends': ['base'],
'data':[
'security/security_estate_property_menu_groups.xml',
'security/security_estate_property_model_groups.xml',
'security/security_estate_property_model_record_rules.xml',
'security/ir.model.access.csv',
//...略
]
}
查看效果

参考连接:https://www.odoo.com/documentation/14.0/zh_CN/developer/reference/addons/security.html#record-rules
ORM字段可以具有提供组列表的groups属性(值为逗号分隔的组XML ID列表,如groups='base.group_user,base.group_system')注意:groups属性值格式:moduleName.groupName,其中moduleName为groupName组所在模块名称,必不可少。
如果当前用户不在列出的组中,他将无权访问该字段:
fields_get()响应中删除受限制的字段尝试(显式的)读取或写入受限字段会导致访问错误
修改estate\security\security_estate_property_model_groups.xml,添加group_estate_property_selling_price_field组
<data noupdate="0">
<!--########################
[房地产]模型记录
########################-->
<record id="group_estate_property_selling_price_field" model="res.groups">
<field name="name">[房地产]模型 售价字段</field>
<field name="category_id" ref="estate_property_model_groups"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
<record id="group_estate_property_record_query" model="res.groups">
<field name="name">[房地产]模型记录 查询</field>
<field name="category_id" ref="estate_property_model_groups"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
</data>
查看效果

修改estate\views\estate_property_views.xml视图selling_price字段,添加groups属性
<field name="selling_price" string="Selling Price" groups="estate.group_estate_property_selling_price_field"/>
验证,发现界面上,未授权上述框选权限的用户已经看不到上述字段了
注意:通过为当前视图中目标字段添加groups属性实现的权限控制仅作用于当前视图,如果希望当前视图模型(Model)的所有视图中,对该字段实现统一的权限控制话,需要在模型定义中,为目标字段添加groups属性,如下:
selling_price = fields.Float('selling price', digits=(8, 2), readonly=True, copy=False, groups="estate.group_estate_property_selling_price_field")
参考连接:https://www.odoo.com/documentation/14.0/zh_CN/developer/reference/addons/security.html#field-access
扩展:在页面从数据库加载视图时,会通过load_view接口,会调用fields_view_get方法,可以重写此方法以控制xml显示的效果(参考网络资料,未实践验证)
类似字段权限控制,仅需在在对应视图中,为目标按钮<button>元素,添加groups属性即可。
base_user_role模块的作用可以简单理解为,按自定义维度将所需权限组组合在一起,组成角色,实现批量授权的功能。
解压下载的base_user_role-12.0.2.1.2.zip文件,对解压后的部分文件做如下修改:
base_user_role\models\user.py,base_user_role\models\role.py
去除上述两个文件中的所有@api.multi修饰符,解决安装报错问题:
AttributeError: module 'odoo.api' has no attribute 'multi'
说明:Odoo 13.0开始,移除multi,multi作为默认实现。
base_user_role/views/role.xml
修改
<record model="ir.actions.act_window" id="action_res_users_role_tree">
<field name="name">Roles</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.users.role</field>
<field name="view_type">form</field>
<field name="view_id" ref="view_res_users_role_tree"/>
</record>
为
<record model="ir.actions.act_window" id="action_res_users_role_tree">
<field name="name">Roles</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.users.role</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_res_users_role_tree"/>
</record>
解决安装报错问题:
odoo.tools.convert.ParseError: while parsing file:/d:/codepojects/odoo14/custom/base_user_role/views/role.xml:63, near
然后,将解压目录下base_user_role整个文件夹拷贝odoo14\custom目录下,最后,重启服务并安装该模块。
安装成功后,Settings -> Users & Companies菜单下,将新增Roles子菜单(笔者实践发现无法通过该页面新增角色并关联用户),Settings -> Users & Companies -> Users 用户记录详情页将新增Roles Tab页
为了统一管理权限组,考虑新增一个单独的应用模块estate_role,模块文件组织结构如下
custom/estate_role
│ __init__.py
│ __manifest__.py
│
├─security
│ security_estate_property_menu_groups.xml
│ security_estate_property_model_groups.xml
│ security_roles.xml
│
└─views
odoo14\custom\estate_role\security\security_roles.xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="group_role_base_user" model="res.users.role">
<field name="name">基础用户</field>
<field name="implied_ids" eval="[
(4, ref('base.group_user')),
]"/>
</record>
<record id="group_role_multi_company" model="res.users.role">
<field name="name">多公司</field>
<field name="implied_ids" eval="[
(4, ref('base.group_multi_company')),
]"/>
</record>
<record id="group_role_devops" model="res.users.role">
<field name="name">运维</field>
<field name="implied_ids" eval="[
(4, ref('estate_role.group_estate_property_root_menu')),
(4, ref('estate_role.group_estate_property_advertisements_menu')),
(4, ref('estate_role.group_estate_property_advertisements_properties_menu')),
(4, ref('estate_role.group_estate_property_read')),
(4, ref('estate_role.group_estate_property_write')),
(4, ref('estate_role.group_estate_property_create'))
]"/>
</record>
</data>
</odoo>
odoo14\custom\estate_role\__init__.py
文件内容为空
odoo14\custom\estate_role\__manifest__.py
{
"name": "Estate Roles",
"license": "LGPL-3",
"depends": ["base_user_role"],
"data": [
"security/security_estate_property_menu_groups.xml",
"security/security_estate_property_model_groups.xml",
"security/security_roles.xml"
],
"installable": True,
}
说明:odoo14\custom\estate\__manifest__.py data列表中已去除上述两个groups文件
重启服务并安装estate_role模块
用户详情页面,查看用户权限,发现新增 User Roles

编辑用户,勾选图中的角色,保存,发现和角色关联的权限组都会被自动勾选了。
注意:
Roles Tab页中显示Access Rights)Tab页面,选取角色为用户批量授权外,还可以在用户详情页的Roles Tab页中为用户添加角色来实现批量授权。https://www.odoo.com/documentation/14.0/zh_CN/developer/reference/addons/security.html
我正在使用i18n从头开始构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在rubyonrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi
我安装了ruby版本管理器,并将RVM安装的ruby实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby。有没有办法让emacs像shell一样尊重ruby的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el
是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s
SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手
大家好,我正在尝试设置一个开发环境,并且我一直在关注以下教程:Linktotutorial我做得不是很好,除了最基本的版本控制内容外,我对终端命令没有任何实际经验。我点击了第一个链接并尝试运行source~/.bash_profile我得到了错误;mkdir:/usr/local/rbenv/shims:权限被拒绝mkdir:/usr/local/rbenv/versions:权限被拒绝现在每次我加载终端时都会出现错误。bash_profile的内容;exportPATH=/usr/local/rbenv/bin:$PATHexportRBENV_ROOT=/usr/local/rbe
我想用这两种语言中的任何一种(最好是ruby)制作一个窗口管理器。老实说,除了我需要加载某种X模块外,我不知道从哪里开始。因此,如果有人有线索,如果您能指出正确的方向,那就太好了。谢谢 最佳答案 XCB,X的下一代API使用XML格式定义X协议(protocol),并使用脚本生成特定语言绑定(bind)。它在概念上与SWIG类似,只是它描述的不是CAPI,而是X协议(protocol)。目前,C和Python存在绑定(bind)。理论上,Ruby端口只是编写一个从XML协议(protocol)定义语言到Ruby的翻译器的问题。生
这是我在ActiveAdmin中的自定义页面ActiveAdmin.register_page"Settings"doaction_itemdolink_to('Importprojects','settings/importprojects')endcontentdopara"Text"endcontrollerdodefimportprojectssystem"rakedataspider:import_projects_ninja"para"OK"endendend我想做的是,当我单击“导入项目”按钮时,我想在Controller中执行rake任务。但是我无法访问该方法。可能是什
我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源
我正在为我的用户实现一些rubyonrails代码推特内容。我正在创建正确的oauth链接...类似http://twitter.com/oauth/authorize?oauth_token=y2RkuftYAEkbEuIF7zKMuzWN30O2XxM8U9j0egtzKv但在我的测试帐户授予对twitter的访问权限后,它会弹出一个页面,上面写着“您已成功授予对.我不知道用户应该在哪里输入此PIN以及他们为什么必须这样做。我认为这不是必要的步骤。Twitter应该将用户重定向到我在应用程序设置中提供的回调URL。有谁知道为什么会这样?更新我找到了thisarticle声明我需
我正在关注Ryan的RailsCast第339集。我已经安装了rbenv并且可以运行ruby-v。我退出了我的session,当我试图返回时(通过root的sudeployer,我得到了这个错误/home/deployer/.rbenv/bin/rbenv:line20:cd:/root:Permissiondenied这是rbenv文件:#!/usr/bin/envbashset-e[-n"$RBENV_DEBUG"]&&set-xresolve_link(){$(type-pgreadlinkreadlink|head-1)"$1"}abs_dirname(){localcwd="