代码之家  ›  专栏  ›  技术社区  ›  Thierry Lam

在rails中,如何向同一个模型添加多个外键?我有相当于Django的

  •  0
  • Thierry Lam  · 技术社区  · 14 年前

    我使用的是rails 3 beta,我假设它的语法与2.x相似,我也不太熟悉ruby和rails。

    在django中,同一模型的多个外键如下所示:

    class Dish(models.Model):
        name = models.CharField(max_length=100)
        lunch = models.ForeignKey(Ingredient, related_name='lunch')
        dinner = models.ForeignKey(Ingredient, related_name='dinner')
    
    class Ingredient(models.Model):
        spices = models.IntegerField()
        veggies = models.IntegerField()
    

    在rails中,我考虑做如下事情:

    # Migration file
    create_table :dishes do |t|
      t.column :name, :string
    end
    
    create_table :ingredients do |t|
      t.column :spice, :integer
      t.column :veggies, :integer
      t.column: :dish_id, :integer
      t.column: :meal, :string  # lunch or dinner
    end
    
    # Models
    class Dish < ActiveRecord::Base
      def lunch
        return # ingredient for the current dish where type == lunch
      end
    
      def dinner
        return # ingredient for the current dish where type == dinner
      end
    end
    

    上面的想法是正确的还是有更好的方法?

    更多澄清: 这家餐厅在午餐和晚餐期间供应同一道菜,但在这两餐之间使用的配料量不同。每道菜最多可包含一个午餐配料对象和一个晚餐配料对象。

    2 回复  |  直到 14 年前
        1
  •  0
  •   klew    14 年前

    首先,对我来说,如果使用string列只存储两种类型的内容,这看起来不太好。当有更多类型的食物时,可以将其存储为布尔值或整数。您可以添加一个数组,该数组将膳食类型id映射到 lunch dinner 或者别的什么。

    # Ingredient model
    belongs_to :dish
    
    def meal
      MEAL_TYPES[meal_id]
    end
    
    private
    MEAL_TYPES = ['lunch', 'dinner']
    
    
    # Dish model
    has_one :lunch, :class_name => 'Ingredient', :conditions => {:meal_id => 0}
    has_one :dinner, :class_name => 'Ingredient', :conditions => {:meal_id => 1}
    

    然后在代码中,您可以将其用作休耕地:

    @dish = Dish.find(params[:id])
    @dish.lunch # returns lunch ingredients
    @dish.dinner # returns dinner ingredients
    
    @dish.lunch.meal # => "lunch"
    
        2
  •  2
  •   Harish Shetty    14 年前

    你的模型不清楚 1-to-1 1-to-n 之间的关系 Dish 模型及 Ingredients 模型。 如果关系是 1对1 ,以下代码应有效:

    class Dish < ActiveRecord::Base
     has_one :lunch, :class_name => 'Ingredient', :conditions => {:meal => 'lunch'}
     has_one :dinnner, :class_name => 'Ingredient', :conditions => {:meal => 'dinner'}
    
    end
    # now you can get lunch and dinner using the calls below on a Dish object.
    dish.lunch
    dish.lunch
    

    如果关系是 1-N ,以下代码应有效:

    class Dish < ActiveRecord::Base
     has_many :lunches, :class_name => 'Ingredient', :conditions => {:meal => 'lunch'}
     has_many :dinnners, :class_name => 'Ingredient', :conditions => {:meal => 'dinner'}
    end