В Rails, как добавить несколько внешних ключей к одной модели? У меня есть эквивалент Django - PullRequest
0 голосов
/ 04 марта 2010

Я использую 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 ]

2 голосов
/ 04 марта 2010

Из вашей модели не ясно, существует ли отношение 1-to-1 или 1-to-n между Dish моделью и Ingredients моделью. Если отношение 1-to-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-to-n, должен работать следующий код:

class Dish < ActiveRecord::Base
 has_many :lunches, :class_name => 'Ingredient', :conditions => {:meal => 'lunch'}
 has_many :dinnners, :class_name => 'Ingredient', :conditions => {:meal => 'dinner'}
end
0 голосов
/ 04 марта 2010

Во-первых, для меня не очень хорошо, если вы используете строковый столбец для хранения только двух типов чего-либо. Вы можете хранить его как логическое или как целое число, когда есть больше видов еды. Вы можете добавить массив, который отображает идентификатор типа еды на 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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...