Задача о последовательности создания светильников Rails - PullRequest
2 голосов
/ 10 февраля 2011

Я читаю книгу Simply Rails от Sitepoint и мне даны следующие модели:

story.rb

class Story < ActiveRecord::Base
    validates_presence_of :name, :link
    has_many :votes do
        def latest
            find :all, :order => 'id DESC', :limit => 3
        end
    end

    def to_param
        "#{id}-#{name.gsub(/\W/, '-').downcase}"
    end
end

voice.rb

class Vote < ActiveRecord::Base
    belongs_to :story
end

и дано это

Stories.yml

one:
  name: MyString
  link: MyString

two:
  name: MyString2
  link: MyString2

voices.yml

one:
  story: one

two:
  story: one

эти тесты не пройдены:

story_test.rb

def test_should_have_a_votes_association
    assert_equal [votes(:one),votes(:two)], stories(:one).votes
  end

def test_should_return_highest_vote_id_first
    assert_equal votes(:two), stories(:one).votes.latest.first
  end

однако, если я переверну порядок рассказов для первого утверждения и предоставлю первый голос за первое утверждение, он пройдет

story_test.rb

def test_should_have_a_votes_association
    assert_equal [votes(:two),votes(:one)], stories(:one).votes
  end

  def test_should_return_highest_vote_id_first
    assert_equal votes(:one), stories(:one).votes.latest.first
  end

Я скопировалвсе как есть в книге и не видели опечаток по этому поводу.Мой первый вывод состоял в том, что прибор создает записи снизу вверх, как было объявлено, но это не имеет никакого смысла

какие-либо идеи?

EDIT : Я использую Rails 2.9 в RVM

Ответы [ 2 ]

8 голосов
/ 10 февраля 2011

Ваши приборы не получают идентификаторы 1, 2, 3 и т. Д., Как вы ожидаете - когда вы добавляете приборы, они получают идентификаторы на основе (я думаю) хеша имени таблицы и имени приспособления. Для нас, людей, они просто выглядят как случайные числа.

Rails делает это, чтобы вы могли легко обращаться к другим приборам по имени. Например, светильники

#parents.yml
vladimir:
  name: Vladimir Ilyich Lenin

#children.yml
joseph:
  name: Joseph Vissarionovich Stalin
  parent: vladimir

фактически отображается в вашей базе данных как

#parents.yml
vladimir:
  id: <%= fixture_hash('parents', 'vladimir') %>
  name: Vladimir Ilyich Lenin

#children.yml
joseph:
  id: <%= fixture_hash('children', 'joseph') %>
  name: Joseph Vissarionovich Stalin
  parent_id: <%= fixture_hash('parents', 'vladimir') %>

Обратите внимание, в частности, на расширение от parent: vladimir до parent_id: <%= ... %> в дочерней модели - так Rails обрабатывает отношения между приборами.

Мораль истории: не рассчитывайте на то, что ваши приборы находятся в каком-либо определенном порядке, и не рассчитывайте на :order => :id, дающую вам значимые результаты в тестах. Используйте results.member? objX несколько раз вместо results == [obj1, obj2, ...]. А если вам нужны фиксированные идентификаторы, напишите их в себе.

Надеюсь, это поможет!

PS: Ленин и Сталин на самом деле не были связаны.

1 голос
/ 03 января 2015

Ксавье Холт уже дал основной ответ, но хотел бы также упомянуть, что можно заставить рельсы читать приборы в определенном порядке.

По умолчанию rails назначает свои собственные идентификаторы, но вы можете использовать спецификацию YAML omap, чтобы указать упорядоченное отображение

# countries.yml
--- !omap
- netherlands:
    id:         1
    title:      Kingdom of Netherlands
- canada:
    id:         2
    title:      Canada

Поскольку вы форсируете заказ, вам также необходимо указать идентификатор самостоятельно, как показано выше.

Кроме того, я не уверен насчет этой части, но я думаю, что как только вы решите переопределить сгенерированный ID рельсов по умолчанию и использовать свой собственный, вы должны сделать то же самое для всех последующих ссылок.

В приведенном выше примере, предположим, что в каждой стране может быть несколько лидеров, вы должны сделать что-то вроде

# leaders.yml
netherlands-leader:
  country_id: 1   #you have to specify this now!
  name: Willem-Alexander

Вам необходимо вручную указать идентификатор, относящийся к предыдущей модели (Страны)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...