2009-11-23 1 views
1

У меня есть несколько моделей:модели отношение проблема с Рубином на Rails

class StatsParent < ActiveRecord::Base 
class CourseStat < StatsParent 
class PlayerCourseStat < CourseStat 

Я имею Course модель настроить как таковой:

class Course < ActiveRecord::Base 
    has_one :course_stat 
    has_many :player_course_stats 

    def update_stats(plyr_rnd) 
    puts self.course_stat # this puts #<PlayerCourseStat:0x000001015c54e0> 
    if self.course_stat 
     self.course_stat.add_player_round(plyr_rnd) 
    else 
     self.course_stat = CourseStat.new(plyr_rnd) 
    end 
    end 
#...rest of the class 

Проблема Я бегу в: В процессе Я проверяю, существует ли файл course_stat и если он его не создает. Но в модели говорится, что она существует, потому что есть player_course_stat, связанный с этим экземпляром.

Когда я погружаюсь в ruby script/console и проверяю, что связь course_stat равна нулю.

> ruby script/console 
Loading development environment (Rails 2.3.3) 
>> course = Course.find(1) 
=> #<Course id: ...> 
>> course.course_stat 
=> nil 
>> course.player_course_stats 
=> [#<PlayerCourseStat id: 1, ...>] 
  1. Есть проблема с тем, как у меня есть отношения для множества моделей курса?
  2. Почему course_stat Ноль в консоли, но не в приложении, поскольку он работает?

Update:

Глядя на это немного дальше, я просмотрел логи, чтобы получить операторы SQL, которые генерируются для консоли и приложения.

# from console: course.course_stat 
CourseStat Load (0.2ms) SELECT * FROM "stats_parents" WHERE 
("stats_parents".course_id = 1) AND (("stats_parents"."type" = 'CourseStat')) 
LIMIT 1 

# from app: course.course_stat 
CourseStat Load (0.3ms) SELECT * FROM "stats_parents" WHERE 
("stats_parents".course_id = 3) AND (("stats_parents"."type" = 'CourseStat' OR 
             "stats_parents"."type" = 'PlayerCourseStat')) 
LIMIT 1 

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

+1

Вы делаете одностраничное наследование? Если да, уверены, что правильно устанавливаете столбец 'type' для модели StatParent? – khelll

+0

STI по ​​умолчанию, и если в миграции есть поле типа: string, оно должно быть автоматически заполнено Rails. –

+0

Я добавил обновление, чтобы показать запущенные запросы. Надеюсь, это поможет выяснить. – lillq

ответ

1

Я думаю, вы должны просто добавить условие к вашему has_one

has_one :course_stat, :conditions => "type = 'CourseStat'" 

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

+0

Спасибо. Это кажется самым простым решением, хотя оно кажется излишним. – lillq

0

Учитывая ваши отношения:

class StatsParent < ActiveRecord::Base 
class CourseStat < StatsParent 
class PlayerCourseStat < CourseStat 

, когда у вас есть PlayerCourseStat, у вас есть стат курс, потому что вы смоделировал-А отношения ... PlayerCourseStat IS-A CourseStat. Возможно, вы имели в виду сделать:

class PlayerCourseStat < StatsParent 
+0

Единственное реальное различие между PlayerCourseStat и CourseStat заключается в том, что PlayerCourseStat связан с пользователем, а CourseStat - нет.Так как они оба обновлены так же, как мне кажется, что PlayerCourseStat наследует от CourseStat, чтобы предотвратить дублирование кода метода обновления. – lillq

1

Если вы хотите сохранить этот простой (всегда хорошая идея), устранить наследование и поставить общую логику в модуле

module Stats 
    def ... 
end 

class CourseStat < ActiveRecord::Base 
    include Stats 
end 

class PlayerCourseStat < ActiveRecord::Base 
    include Stats 
end