首页 \ 问答 \ 停止在Rails中验证的关联5(Stop Associations from Validating in Rails 5)

停止在Rails中验证的关联5(Stop Associations from Validating in Rails 5)

使用Rails 5,我正在尝试实现Omniauth-Facebook和Clearance用于用户身份验证。

注意:我的代码与此Gist完全相同

我得到它主要工作。 但是,当使用Facebook注册(即用户从未访问过该网站)时,Rails会抛出一个错误,说Validation failed: User must exist 。 我已经把问题缩小到了Gist中的这个块:

  def self.create_with_omniauth(auth_hash)
    create! do |auth|
      auth.provider = auth_hash["provider"]
      auth.uid = auth_hash["uid"]
      auth.token = auth_hash["credentials"]["token"]
    end
  end

当它击中时,它试图create! 没有auth.user对象,并且失败。 以下是sessions控制器的相关代码:

#-- Spectically, the line below
authentication = Authentication.find_by_provider_and_uid(auth_hash["provider"], auth_hash["uid"]) || Authentication.create_with_omniauth(auth_hash)
#-- More code, for context
if authentication.user
  user = authentication.user 
  authentication.update_token(auth_hash)
  @next = root_url
  @notice = "Signed in!"
else
  user = User.create_with_auth_and_hash(authentication,auth_hash)
  @next = edit_user_path(user)   
  @notice = "User created - confirm or edit details..."
end

我在Gist中唯一遗漏的是他的Authentications表的结构。 使用我发现的上下文线索,我创建了这个表:

  def change
    create_table :authentications do |t|
      t.string :provider
      t.string :uid
      t.string :token
      t.references :user, foreign_key: true

      t.timestamps
    end
  end

如果需要更多信息,我会尽我所能


Using Rails 5, I'm trying to implement Omniauth-Facebook and Clearance for user authentication.

Note: My code is exactly like this Gist

I've gotten it mostly working. However when using Facebook to register (ie a user has never visited the site), Rails throws an error saying Validation failed: User must exist. I've narrowed down the problem to this block in the Gist:

  def self.create_with_omniauth(auth_hash)
    create! do |auth|
      auth.provider = auth_hash["provider"]
      auth.uid = auth_hash["uid"]
      auth.token = auth_hash["credentials"]["token"]
    end
  end

When it hits that, it tries to create! without a auth.user object present, and fails. Here is the relevant code from the sessions controller:

#-- Spectically, the line below
authentication = Authentication.find_by_provider_and_uid(auth_hash["provider"], auth_hash["uid"]) || Authentication.create_with_omniauth(auth_hash)
#-- More code, for context
if authentication.user
  user = authentication.user 
  authentication.update_token(auth_hash)
  @next = root_url
  @notice = "Signed in!"
else
  user = User.create_with_auth_and_hash(authentication,auth_hash)
  @next = edit_user_path(user)   
  @notice = "User created - confirm or edit details..."
end

The only thing I'm missing out of the Gist is the structure of his Authentications table. Using the context clues I found, I created this table:

  def change
    create_table :authentications do |t|
      t.string :provider
      t.string :uid
      t.string :token
      t.references :user, foreign_key: true

      t.timestamps
    end
  end

If any more information is needed, I'll provide what I can


原文:https://stackoverflow.com/questions/36343793
更新时间:2022-11-20 11:11

最满意答案

使用C99可变长度数组(VLA)功能使问题变得简单。 C11支持VLA可选,但实现必须定义__STDC_NO_VLA__以表明它不支持VLA。

这是代码的一个版本。 我重命名了Turn()函数(它将矩阵右转90°为TurnR()并添加了一个TurnL()函数,该矩阵将矩阵向左旋转90°由于代码处理非平方矩阵,因此输出矩阵是分开的从输入矩阵(如果你只想使用平方矩阵,可以稍微简化代码)。

#include <stdio.h>

static void TurnR(size_t rows, size_t cols, int matrix[rows][cols], int result[cols][rows])
{
    for (size_t r = 0; r < rows; r++)
    {
        for (size_t c = 0; c < cols; c++)
            result[c][rows - 1 - r] = matrix[r][c];
    }
}

static void TurnL(size_t rows, size_t cols, int matrix[rows][cols], int result[cols][rows])
{
    for (size_t r = 0; r < rows; r++)
    {
        for (size_t c = 0; c < cols; c++)
            result[cols - 1 - c][r] = matrix[r][c];
    }
}

static void Print(const char *tag, size_t rows, size_t cols, int matrix[rows][cols])
{
    printf("%s (%zux%zu):\n", tag, rows, cols);
    for (size_t r = 0; r < rows; r++)
    {
        const char *pad = "";
        for (size_t c = 0; c < cols; c++)
        {
            printf("%s%3d", pad, matrix[r][c]);
            pad = " ";
        }
        putchar('\n');
    }
}

int main(void)
{
    int BY[4][4] = {
        {  1,  2,  3,  4, },
        {  5,  6,  7,  8, },
        {  9, 10, 11, 12, },
        { 13, 14, 15, 16, },
    };
    int out[4][4];

    Print("before", 4, 4, BY);
    TurnR(4, 4, BY, out);
    Print("right", 4, 4, out);
    TurnL(4, 4, BY, out);
    Print("left", 4, 4, out);

    int m4x6[4][6] =
    {
        {  1,  2,  3,  4,  5,  6, },
        {  7,  8,  9, 10, 11, 12, },
        { 13, 14, 15, 16, 17, 18, },
        { 19, 20, 21, 22, 23, 24, },
    };
    int m6x4[6][4];

    Print("before", 4, 6, m4x6);
    TurnR(4, 6, m4x6, m6x4);
    Print("right", 6, 4, m6x4);
    TurnL(4, 6, m4x6, m6x4);
    Print("left", 6, 4, m6x4);

    int m5x3[5][3] =
    {
        {  1,  2,  3, },
        {  4,  5,  6, },
        {  7,  8,  9, },
        { 10, 11, 12, },
        { 13, 14, 15, },
    };
    int m3x5[3][5];

    Print("before", 5, 3, m5x3);
    TurnR(5, 3, m5x3, m3x5);
    Print("right", 3, 5, m3x5);
    TurnL(5, 3, m5x3, m3x5);
    Print("left", 3, 5, m3x5);
    TurnL(3, 5, m3x5, m5x3);
    Print("doubleL", 5, 3, m5x3);

    return 0;
}

并且示例输出是:

before (4x4):
  1   2   3   4
  5   6   7   8
  9  10  11  12
 13  14  15  16
right (4x4):
 13   9   5   1
 14  10   6   2
 15  11   7   3
 16  12   8   4
left (4x4):
  4   8  12  16
  3   7  11  15
  2   6  10  14
  1   5   9  13
before (4x6):
  1   2   3   4   5   6
  7   8   9  10  11  12
 13  14  15  16  17  18
 19  20  21  22  23  24
right (6x4):
 19  13   7   1
 20  14   8   2
 21  15   9   3
 22  16  10   4
 23  17  11   5
 24  18  12   6
left (6x4):
  6  12  18  24
  5  11  17  23
  4  10  16  22
  3   9  15  21
  2   8  14  20
  1   7  13  19
before (5x3):
  1   2   3
  4   5   6
  7   8   9
 10  11  12
 13  14  15
right (3x5):
 13  10   7   4   1
 14  11   8   5   2
 15  12   9   6   3
left (3x5):
  3   6   9  12  15
  2   5   8  11  14
  1   4   7  10  13
doubleL (5x3):
 15  14  13
 12  11  10
  9   8   7
  6   5   4
  3   2   1

我不会想用*(ptr + index)符号编写代码,尤其是使用双下标; 它太容易出错,难以阅读(确实是一场噩梦!)。


Using the C99 variable length array (VLA) feature make the problem easy. C11 makes support for VLAs optional, but the implementation must define __STDC_NO_VLA__ to show that it doesn't support VLAs.

Here's one version of the code. I've renamed your Turn() function (which turns the matrix 90° right into TurnR() and added a TurnL() function which turns the matrix 90° left. Because the code handles non-square matrices, the output matrix is separate from the input matrix. (You can simplify the code slightly if you only want to work with square matrices.)

#include <stdio.h>

static void TurnR(size_t rows, size_t cols, int matrix[rows][cols], int result[cols][rows])
{
    for (size_t r = 0; r < rows; r++)
    {
        for (size_t c = 0; c < cols; c++)
            result[c][rows - 1 - r] = matrix[r][c];
    }
}

static void TurnL(size_t rows, size_t cols, int matrix[rows][cols], int result[cols][rows])
{
    for (size_t r = 0; r < rows; r++)
    {
        for (size_t c = 0; c < cols; c++)
            result[cols - 1 - c][r] = matrix[r][c];
    }
}

static void Print(const char *tag, size_t rows, size_t cols, int matrix[rows][cols])
{
    printf("%s (%zux%zu):\n", tag, rows, cols);
    for (size_t r = 0; r < rows; r++)
    {
        const char *pad = "";
        for (size_t c = 0; c < cols; c++)
        {
            printf("%s%3d", pad, matrix[r][c]);
            pad = " ";
        }
        putchar('\n');
    }
}

int main(void)
{
    int BY[4][4] = {
        {  1,  2,  3,  4, },
        {  5,  6,  7,  8, },
        {  9, 10, 11, 12, },
        { 13, 14, 15, 16, },
    };
    int out[4][4];

    Print("before", 4, 4, BY);
    TurnR(4, 4, BY, out);
    Print("right", 4, 4, out);
    TurnL(4, 4, BY, out);
    Print("left", 4, 4, out);

    int m4x6[4][6] =
    {
        {  1,  2,  3,  4,  5,  6, },
        {  7,  8,  9, 10, 11, 12, },
        { 13, 14, 15, 16, 17, 18, },
        { 19, 20, 21, 22, 23, 24, },
    };
    int m6x4[6][4];

    Print("before", 4, 6, m4x6);
    TurnR(4, 6, m4x6, m6x4);
    Print("right", 6, 4, m6x4);
    TurnL(4, 6, m4x6, m6x4);
    Print("left", 6, 4, m6x4);

    int m5x3[5][3] =
    {
        {  1,  2,  3, },
        {  4,  5,  6, },
        {  7,  8,  9, },
        { 10, 11, 12, },
        { 13, 14, 15, },
    };
    int m3x5[3][5];

    Print("before", 5, 3, m5x3);
    TurnR(5, 3, m5x3, m3x5);
    Print("right", 3, 5, m3x5);
    TurnL(5, 3, m5x3, m3x5);
    Print("left", 3, 5, m3x5);
    TurnL(3, 5, m3x5, m5x3);
    Print("doubleL", 5, 3, m5x3);

    return 0;
}

And sample output is:

before (4x4):
  1   2   3   4
  5   6   7   8
  9  10  11  12
 13  14  15  16
right (4x4):
 13   9   5   1
 14  10   6   2
 15  11   7   3
 16  12   8   4
left (4x4):
  4   8  12  16
  3   7  11  15
  2   6  10  14
  1   5   9  13
before (4x6):
  1   2   3   4   5   6
  7   8   9  10  11  12
 13  14  15  16  17  18
 19  20  21  22  23  24
right (6x4):
 19  13   7   1
 20  14   8   2
 21  15   9   3
 22  16  10   4
 23  17  11   5
 24  18  12   6
left (6x4):
  6  12  18  24
  5  11  17  23
  4  10  16  22
  3   9  15  21
  2   8  14  20
  1   7  13  19
before (5x3):
  1   2   3
  4   5   6
  7   8   9
 10  11  12
 13  14  15
right (3x5):
 13  10   7   4   1
 14  11   8   5   2
 15  12   9   6   3
left (3x5):
  3   6   9  12  15
  2   5   8  11  14
  1   4   7  10  13
doubleL (5x3):
 15  14  13
 12  11  10
  9   8   7
  6   5   4
  3   2   1

I wouldn't dream of writing the code using the *(ptr + index) notation, especially with the double subscripts; it is just too error prone and hard to read (a nightmare, indeed!).

相关问答

更多
  • 使用C99可变长度数组(VLA)功能使问题变得简单。 C11支持VLA可选,但实现必须定义__STDC_NO_VLA__以表明它不支持VLA。 这是代码的一个版本。 我重命名了Turn()函数(它将矩阵右转90°为TurnR()并添加了一个TurnL()函数,该矩阵将矩阵向左旋转90°由于代码处理非平方矩阵,因此输出矩阵是分开的从输入矩阵(如果你只想使用平方矩阵,可以稍微简化代码)。 #include static void TurnR(size_t rows, size_t cols ...
  • SVD是一种很好的方法(可能)。 LSA(潜在语义分析)基于它,并且具有基本相同的维度方法。 我已经谈到了(最后): lsa-latent-semantic-analysis-how-to-code-it-in-php或者在SO上查看LSA标签。 我意识到这是一个不完整的答案。 霍勒,如果你想要更多的帮助! SVD is a fine approach (probably). LSA (Latent Semantic Analysis) is based around it, and has basical ...
  • 如果您希望在用户拨打没有参数的呼叫时执行某个功能,请为您的参数指定一个默认值: void foo(double d = 0.0) { ... } void foo(int i) { ... } void foo(char c) { ... } 当用户调用foo() ,将调用double的重载。 代码将被执行,就像传递了零一样。 If you want a function to execute when users make a call with no parameters, g ...
  • 最简单的方法是在表单中添加一个Panel (如果你不想在视觉上看到它,可以使它透明且没有边框),并将两个标签放在该面板中(让它们成为该面板的子项),他们的Dock属性设置为Top 。 还有很多其他方法可以实现您所瞄准的目标,但最简单的方法是“面板+对接”模式。 The easiest way would be adding a Panel to your form (you can make it transparent and without border if you don't want to vis ...
  • 我想你想要typeof results[i].also_known_as === "undefined" (没有[0] )。 目前,代码正在尝试查找数组中的元素,然后检查该元素是否未定义; 由于数组本身是未定义的,因此在尝试查找数组元素之前,它甚至会在检查元素是否未定义之前发生错误。 I think you wanted typeof results[i].also_known_as === "undefined" (without the [0]). Currently the code is tryin ...
  • 要将二维数组作为参数传递: void calcQrtSales (Corpsales[][] qrtsalesarray) { totSales += qrtsalesarray[div][qtr]; } To pass a two-dimensional array as a parameter: void calcQrtSales (Corpsales[][] qrtsalesarray) { totSales += qrtsalesarray[div][qtr]; }
  • 我想你希望prec_double和rad_cool_double是numpy数组。 在这里你已经将它们定义为列表。 n=731 m=180 l=720 prec_double=[[n],[m],[l]] 将导致prec_double成为列表 [[731], [180], [720]] 你想用numpy数组创建这些变量 prec_double = np.zeros([n,m,l]) 这将填满零。 I think you want prec_double and rad_cool_double t ...
  • 请改用Dimension.setSize(double,double) 。 Use Dimension.setSize(double,double) instead.
  • 它是指向VEC_SIZE双精度数组的指针。 这是VEC_SIZE的X数组的数组加倍衰减的类型。 在代码中: double arr[X][VEC_SIZE] = { /* ... */ }; double a, b; closestPair(arr, X, &a, &b); 您还可以传递普通数组的地址: double arr[VEC_SIZE]; double a, b; closestPair(&arr, 1, &a, &b); It's a pointer to an array of VEC_SI ...
  • 如果要使用可变大小数组作为参数,则需要先指定大小,然后将该参数用作数组参数中的数组大小: int diagonal(int N, int A[N][N] ); int main() { ... diagonal(N, array); } int diagonal(int N, int A[N][N]){ ... } If you want to use a variable size array as an argument, you need to specify the s ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。