如何将其他列的值复制为rails迁移中新列的默认值?

时间:2017-01-19 13:41:59

标签: ruby-on-rails activerecord migration

我有一个列price的模型。我需要添加一个值为marked_price的new_column price作为默认值。我可以在迁移中写这个,或者最好的方法是什么?

类似的东西:

class AddMarkedPriceToMenuItems < ActiveRecord::Migration
  def change
    add_column :menu_items, :marked_price, :decimal, :default => :price
  end
end

2 个答案:

答案 0 :(得分:10)

不,数据库不允许您使用表格列上的DEFAULT设置执行此操作。

但您可以使用 ActiveRecord 回调

来完成此操作
class MenuItem < ActiveRecord::Base
  before_create :set_market_price_default

  private

  def set_market_price_default
    self.market_price = self.price
  end
end

至于迁移本身,您可以手动更新market_price

def change
  add_column :menu_items, :marked_price, :decimal

  reversible do |dir|
    dir.up { MenuItem.update_all('marked_price = price') }
  end
end

请注意,您可能希望创建本地迁移模型的副本,以便将来不会失去同步。

答案 1 :(得分:0)

这是一种通用的解决方法,无需编写查询,因为查询会面临风险。

#define MAX 1000

int checkSpelling(const char *input, const char *dict);
int searchReplace(const char *input, const char *dict);
int save(const char *input, const char *output);

int main (int argc, char **argv){
    int choice = 0;

    if(argc != 4){
            printf("Not enough input arguments in the command line.\n");
            exit(1);
    }

    do{
            printf("Menu\n");
            printf("1. Check the spelling for the file using the dictionary.\n");
            printf("2. Search and replace a given string in the inputed file.\n");
            printf("3. Save the modified file to the output file.\n");
            printf("4. Exit the program.\n");
            scanf("%d", &choice);

            switch(choice){
                    case 1:
                            checkSpelling(argv[1], argv[3]);
                            break;
                    case 2:
                            searchReplace(argv[1], argv[3]);
                            break;
                    case 3:
                            save(argv[1],argv[2]);
                            break;
                    case 4:
                            choice = 4;
                            break;
                    default:
                            printf("Input is invalid");
                            break;
            }

     }while (choice != 4);
return 0;
}

int checkSpelling(const char *input, const char *dict){

    FILE *inputFile;
    FILE *dictFile;
    char temp[MAX] = {0}, dicttemp[MAX];
    int i = 0;
    char *pInput, *pDict;

    printf("Checking the spelling of the inputed file.\n");
    printf("Opening the inputed file...\n");
    if((inputFile = fopen(input, "rt")) == NULL){
            printf("Cannot open file\n");
            exit(1);
    }

    printf("Opening the dictonary...\n");
    if((dictFile = fopen(dict, "rt")) == NULL){
            printf("Cannot open dictionary\n");
            exit(1);
    }

    pInput = (char *)malloc(MAX * sizeof(char));
    pDict = (char *)malloc(MAX * sizeof(char));

    //putting the information from input file into one long array called temp
    while(feof(inputFile)){
            temp[i++] = fgetc(inputFile);
    }
    temp[i] = '\0';

    i = 0;
    for(i = 0; i < MAX; i++){
       printf("%c", temp[i]);
    }
    printf("\n");
    fclose(dictFile);
    fclose(inputFile);
return 0;
}

 int searchReplace(const char *input, const char *dict){

return 0;
 }

//Moves the data from the input file into the output file and saves it
int save(const char *input, const char *output){
    FILE *inputFile;
    FILE *outputFile;

    if((inputFile = fopen(input, "rt")) == NULL){
            printf("Unable to open input file.\n");
            exit(1);
    }

    if((outputFile = fopen(output, "wt"))== NULL){
            printf("Unable to open output file.\n");
            exit(1);
    }

    fclose (inputFile);
    fclose (outputFile);
return 0;
}