草庐IT

android - 重新打开 sqlcipher DB 时创建表 android_metadata 失败

coder 2023-11-20 原文

我有以下 SqlCipher 数据库。当我第一次安装该应用程序时它工作正常,但如果我关闭,从最近的历史记录中删除该应用程序(从堆栈中删除)并重新打开它崩溃并出现以下错误的应用程序。一旦遇到异常,数据库将不会打开,例如我在 Activity 中放置一个 1/0 以强制它崩溃,下面发生了同样的事情。

07-20 15:39:05.669: E/Database(21425): CREATE TABLE android_metadata failed
07-20 15:39:05.669: E/Database(21425): Failed to setLocale() when constructing, closing the database
07-20 15:39:05.669: E/Database(21425): net.sqlcipher.database.SQLiteException: file is encrypted or is not a database

.

我发现以下链接似乎可以解决问题(我不确定它是否是解决方案)但我不确定如何将其实现到我的代码中。谁能帮忙或告诉我为什么会出现此错误?

http://rootslash.net/88542/sqlcipher-cant-open-database-after-apprestart

这是我的数据库代码,我使用 SqlCipher SQLiteOpenHelper 创建数据库。我想我需要修改这段代码,以便它返回一个 DB 对象,如果它已经存在,如果它不存在则创建一个。我只是不确定如何。

提前致谢。

[编辑1] 我有一个验证用户凭据的 LoginActivity。如果它们有效,它会加载 MenuActivity,我在其中放置了 1/0 以强制崩溃。崩溃后,如果我重新打开应用程序,它会在查询数据库用户表的行的 LoginActivity 中崩溃。

DBModel 是一个具有 SqliteOpenHelper 和 CRUD 方法的类。

所以它在 DBModel 类中的 checkUserInDB() 处崩溃,而后者又调用了 queryAllFromUser()。

07-25 13:45:43.043  10654-10654/? E/AppObj﹕ Build.SERIAL = SH43PWM07311
07-25 13:45:43.203  10654-10654/? E/AppObj﹕ secretKey = com.android.org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey@31a79cea
07-25 13:45:43.643  10654-10654/? E/Database﹕ CREATE TABLE android_metadata failed
07-25 13:45:43.643  10654-10654/? E/Database﹕ Failed to setLocale() when constructing, closing the database
    net.sqlcipher.database.SQLiteException: file is encrypted or is not a database
            at net.sqlcipher.database.SQLiteDatabase.native_setLocale(Native Method)
            at net.sqlcipher.database.SQLiteDatabase.setLocale(SQLiteDatabase.java:2096)
            at net.sqlcipher.database.SQLiteDatabase.<init>(SQLiteDatabase.java:1962)
            at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:881)
            at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:913)
            at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:132)
            at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:197)
            at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:184)
            at devreach.co.uk.devreach.DBModel.queryAllFromUser(DBModel.java:175)
            at devreach.co.uk.devreach.DBModel.checkIfUserInDB(DBModel.java:262)
            at devreach.co.uk.devreach.LoginActivity.onCreate(LoginActivity.java:62)
            at android.app.Activity.performCreate(Activity.java:5958)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2474)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1359)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:155)
            at android.app.ActivityThread.main(ActivityThread.java:5696)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
07-25 13:45:43.643  10654-10654/? E/SQLiteOpenHelper﹕ Couldn't open devreach.db for writing (will try read-only):
    net.sqlcipher.database.SQLiteException: file is encrypted or is not a database
            at net.sqlcipher.database.SQLiteDatabase.native_setLocale(Native Method)
            at net.sqlcipher.database.SQLiteDatabase.setLocale(SQLiteDatabase.java:2096)
            at net.sqlcipher.database.SQLiteDatabase.<init>(SQLiteDatabase.java:1962)
            at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:881)
            at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:913)
            at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:132)
            at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:197)
            at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:184)
            at devreach.co.uk.devreach.DBModel.queryAllFromUser(DBModel.java:175)
            at devreach.co.uk.devreach.DBModel.checkIfUserInDB(DBModel.java:262)
            at devreach.co.uk.devreach.LoginActivity.onCreate(LoginActivity.java:62)
            at android.app.Activity.performCreate(Activity.java:5958)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2474)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1359)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:155)
            at android.app.ActivityThread.main(ActivityThread.java:5696)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
07-25 13:45:43.983  10654-10654/? E/Database﹕ CREATE TABLE android_metadata failed
07-25 13:45:43.983  10654-10654/? E/Database﹕ Failed to setLocale() when constructing, closing the database
    net.sqlcipher.database.SQLiteException: file is encrypted or is not a database
            at net.sqlcipher.database.SQLiteDatabase.native_setLocale(Native Method)
            at net.sqlcipher.database.SQLiteDatabase.setLocale(SQLiteDatabase.java:2096)
            at net.sqlcipher.database.SQLiteDatabase.<init>(SQLiteDatabase.java:1962)
            at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:881)
            at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:940)
            at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:219)
            at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:184)
            at devreach.co.uk.devreach.DBModel.queryAllFromUser(DBModel.java:175)
            at devreach.co.uk.devreach.DBModel.checkIfUserInDB(DBModel.java:262)
            at devreach.co.uk.devreach.LoginActivity.onCreate(LoginActivity.java:62)
            at android.app.Activity.performCreate(Activity.java:5958)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2474)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1359)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:155)
            at android.app.ActivityThread.main(ActivityThread.java:5696)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
07-25 13:45:43.983  10654-10654/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: devreach.co.uk.devreach, PID: 10654
    java.lang.RuntimeException: Unable to start activity ComponentInfo{devreach.co.uk.devreach/devreach.co.uk.devreach.LoginActivity}: net.sqlcipher.database.SQLiteException: file is encrypted or is not a database
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2411)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2474)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1359)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:155)
            at android.app.ActivityThread.main(ActivityThread.java:5696)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
     Caused by: net.sqlcipher.database.SQLiteException: file is encrypted or is not a database
            at net.sqlcipher.database.SQLiteDatabase.native_setLocale(Native Method)
            at net.sqlcipher.database.SQLiteDatabase.setLocale(SQLiteDatabase.java:2096)
            at net.sqlcipher.database.SQLiteDatabase.<init>(SQLiteDatabase.java:1962)
            at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:881)
            at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:940)
            at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:219)
            at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:184)
            at devreach.co.uk.devreach.DBModel.queryAllFromUser(DBModel.java:175)
            at devreach.co.uk.devreach.DBModel.checkIfUserInDB(DBModel.java:262)
            at devreach.co.uk.devreach.LoginActivity.onCreate(LoginActivity.java:62)
            at android.app.Activity.performCreate(Activity.java:5958)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2474)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1359)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:155)
            at android.app.ActivityThread.main(ActivityThread.java:5696)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)

登录 Activity :

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        appObj = (AppObj)getApplication();
        editTextFirstName = (EditText)findViewById(R.id.edittextfirstname);
        editTextPassword = (EditText)findViewById(R.id.editTextpassword);

        String firstName = appObj.dbModel.checkIfUserInDB();

        if(! firstName.equalsIgnoreCase("NO_USER")){

            editTextFirstName.setText(firstName);
        }

数据库模型:

    import net.sqlcipher.Cursor;
        import net.sqlcipher.database.SQLiteDatabase;
        import net.sqlcipher.database.SQLiteOpenHelper;
        import android.content.ContentValues;
        import android.content.Context;
        import android.provider.BaseColumns;
        import android.util.Log;
        import android.widget.Toast;



public class DBModel {



    private static final String TAG = DBModel.class.getSimpleName();


    // table user column names
    public static final String C_USER_ID_INDEX = BaseColumns._ID;
    public static final String C_USER_ID = "userid";
    public static final String C_USER_COMP_ID = "usercompid";
    public static final String C_USER_FIRSTNAME = "userfirstname";
    public static final String C_USER_LASTNAME = "userlastname";
    public static final String C_USER_PASSWORD = "userpassword";
    public static final String C_USER_DATE_TIME = "userdatetime";




    // table company column names
    public static final String C_COMPANY_ID_INDEX = BaseColumns._ID;
    public static final String C_COMPANY_ID = "companyid";
    public static final String C_COMPANY_NAME = "companyname";
    public static final String C_COMPANY_URL = "companyurl";
    public static final String C_COMPANY_GUID = "companyguid";







    Context context;
    DBHelper dbhelper;
    AppObj appObj;



    public DBModel(Context context) {

        this.context = context;
        dbhelper = new DBHelper();
        appObj = (AppObj) context.getApplicationContext();


    }




    /**
     * inner class to create/open/upgrade database
     *
     * @author matt
     *
     */
    private class DBHelper extends SQLiteOpenHelper {

        // database name and version number
        public static final String DB_NAME = "devreach.db";
        public static final int DB_VERSION = 1;

        // table names

        public static final String TABLEUSER = "user";
        public static final String TABLECOMPANY = "company";



        public DBHelper() {
            super(context, DB_NAME, null, DB_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {

            Log.e(TAG, "SQLiteOpenHelper oncreate ");





            String sqlToCreateUserTable = String
                    .format("create table %s ( %s INTEGER primary key, %s TEXT, %s TEXT, %s TEXT, %s TEXT, %s TEXT, %s TEXT)",
                            TABLEUSER, C_USER_ID_INDEX, C_USER_ID, C_USER_COMP_ID,
                            C_USER_FIRSTNAME, C_USER_LASTNAME, C_USER_PASSWORD,
                            C_USER_DATE_TIME);

            db.execSQL(sqlToCreateUserTable);
            Log.e(TAG, "oncreate " + sqlToCreateUserTable);




            String sqlToCreateCompanyTable = String
                    .format("create table %s ( %s INTEGER primary key, %s TEXT, %s TEXT, %s TEXT, %s TEXT)",
                            TABLECOMPANY, C_COMPANY_ID_INDEX, C_COMPANY_ID, C_COMPANY_NAME,
                            C_COMPANY_URL, C_COMPANY_GUID);

            db.execSQL(sqlToCreateCompanyTable);
            Log.e(TAG, "oncreate " + sqlToCreateCompanyTable);






        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {




        }//end of onUpgrade

    }//end of DBHelper

    public void close() {

        dbhelper.close();
    }









    public void deleteTableUser() {
        // open database
        SQLiteDatabase db = dbhelper.getWritableDatabase(AppObj.getSecretKey().toString());

        // delete contents of table
        db.delete(DBHelper.TABLEUSER, null, null);


    }

    public void insertIntoUser(ContentValues cv) {

        SQLiteDatabase db = dbhelper.getWritableDatabase(AppObj.getSecretKey().toString());

        db.insertWithOnConflict(DBHelper.TABLEUSER, null, cv, SQLiteDatabase.CONFLICT_REPLACE);

    }



    public Cursor queryAllFromUser() {

        // open database
        SQLiteDatabase db = dbhelper.getReadableDatabase(AppObj.getSecretKey().toString());

        return db.query(DBHelper.TABLEUSER, null, null, null, null, null, null);

    }



    public void deleteTableCompany() {
        // open database
        SQLiteDatabase db = dbhelper.getWritableDatabase(AppObj.getSecretKey().toString());

        // delete contents of table
        db.delete(DBHelper.TABLECOMPANY, null, null);


    }


    public void insertIntoCompany(ContentValues cv) {

        SQLiteDatabase db = dbhelper.getWritableDatabase(AppObj.getSecretKey().toString());

        db.insertWithOnConflict(DBHelper.TABLECOMPANY, null, cv, SQLiteDatabase.CONFLICT_REPLACE);

    }



    public Cursor queryAllFromCompany() {

        // open database
        SQLiteDatabase db = dbhelper.getReadableDatabase(AppObj.getSecretKey().toString());

        return db.query(DBHelper.TABLECOMPANY, null, null, null, null, null, null);

    }


    public String getCompanyGuid(){

        String guid = null;
        Cursor c = null;
        SQLiteDatabase db = dbhelper.getReadableDatabase(AppObj.getSecretKey().toString());

        c = db.query(DBHelper.TABLECOMPANY, null, null, null, null, null, null);

        if(c != null){
            if(c.moveToLast()){

                guid = c.getString(c.getColumnIndex(DBModel.C_COMPANY_GUID));
            }
        }

        try{
            c.close();
        }catch(Exception e){}

        return guid;
    }

    public String getCompanyID(){

        String id = null;
        Cursor c = null;
        SQLiteDatabase db = dbhelper.getReadableDatabase(AppObj.getSecretKey().toString());

        c = db.query(DBHelper.TABLECOMPANY, null, null, null, null, null, null);

        if(c != null){
            if(c.moveToLast()){

                id = c.getString(c.getColumnIndex(DBModel.C_COMPANY_ID));
            }
        }

        try{
            c.close();
        }catch(Exception e){}

        return id;
    }


    public String checkIfUserInDB() {

        String firstName = null;
        Cursor c = queryAllFromUser();

        if(c != null && c.getCount() > 0){
            if(c.moveToLast()){

                Log.e(TAG,"c != null and > 0");
                firstName = c.getString(c.getColumnIndex(DBModel.C_USER_FIRSTNAME));

            }

        }else{
            Log.e(TAG,"c == null");
            firstName = "NO_USER";

        }

        try{
            c.close();
        }catch(Exception e){}

        Log.e(TAG,"firstName = " + firstName);
        return firstName;
    }








}//end of DBModel

[编辑2]

   @Override
        public void onCreate() {
            super.onCreate();

            secretKey = null;
            Log.e(TAG, "Build.SERIAL = " + Build.SERIAL);

            SecureRandom secureRandom = new SecureRandom();
            byte[] salt = secureRandom.generateSeed(256);


            try {
                secretKey = generateKey(Build.SERIAL.toCharArray(), salt);
                 Log.e(TAG, "key-Base64 before in appObj = "+new String(Base64.encode(RROnCallApplication.getSecretKey().getEncoded(),0)));
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvalidKeySpecException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            Log.e(TAG, "secretKey = " + secretKey);

            SQLiteDatabase.loadLibs(this);

            dbModel = new DBModel(this);
            webService = new WebService(this);
            alertCount = 0;

    //      Cursor checkCarerTable = dbModel.queryAllFromCarer();
    //      
    //      if(checkCarerTable.getCount() == 0){
    //      
    //      //runGetCarersService();
    //      //runGetClientsService();
    //      
    //      
    //      }else{
    //          
    //          Log.e(TAG, "carer and client table is populated with some data"); 
    //      }



        }

private static SecretKey generateKey(char[] passphraseOrPin, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
    // Number of PBKDF2 hardening rounds to use. Larger values increase
    // computation time. You should select a value that causes computation
    // to take >100ms.
    final int iterations = 1000; 

    // Generate a 256-bit key
    final int outputKeyLength = 256;

    SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    KeySpec keySpec = new PBEKeySpec(passphraseOrPin, salt, iterations, outputKeyLength);
    SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);

    return secretKey;
}

最佳答案

盐必须与要散列以创建 key 的变量相同。

变量可能会保持不变,相同的用户/用户密码,但是您的代码正在重新生成随机盐。

如果您使用 key 加密数据库,则 key 必须相同,因此盐也必须相同。

希望对您有所帮助!

关于android - 重新打开 sqlcipher DB 时创建表 android_metadata 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31519553/

有关android - 重新打开 sqlcipher DB 时创建表 android_metadata 失败的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  3. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  4. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

    我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

  5. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  6. ruby - 如何使用 RSpec::Core::RakeTask 创建 RSpec Rake 任务? - 2

    如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake

  7. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

    我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

  8. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

  9. ruby - 即使失败也继续进行多主机测试 - 2

    我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r

  10. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

随机推荐