Отношения с базой данных Rails

У меня есть три модели, которые я хочу взаимодействовать друг с другом.

Касе, человек и компания.

Я (я думаю) правильно настроил отношения:

class Kase < ActiveRecord::Base
#HAS ONE COMPANY
has_one :company

#HAS MANY PERSONS
has_many :persons


class Person < ActiveRecord::Base
belongs_to :company

class Company < ActiveRecord::Base
has_many :persons
def to_s; companyname; end

Я поместил поле выбора в новое представление Kase и создал новое представление Person следующим образом:

<li>Company<span><%= f.select :company_id, Company.all %> </span></li>

Все вышеперечисленное успешно показывает выпадающее меню, динамически заполняемое названиями компаний в компаниях.

То, что я пытаюсь сделать, это отобразить контакт записи компании в касе и человеке show.html.erb.

Например, если у меня есть компания под названием "Acme, Inc." и создайте новый Kase под названием «Random Case» и выберите на странице создания нового дела «Acme, Inc.» из выпадающего меню компаний. Затем я хотел бы отобразить «Acme, Inc» вместе с «Acme, Inc. Mobile» и т. Д. В «Случайном случае» show.html.erb.

Я надеюсь, что это имеет смысл для кого-то!

Спасибо,

Дэнни

РЕДАКТИРОВАТЬ: kases_controller

def show
@kase = Kase.find(params[:id])

respond_to do |format|
  format.html # show.html.erb
  format.xml  { render :xml => @kase }
  format.pdf { render :layout => false }

  prawnto :prawn => { 
             :background => "#{RAILS_ROOT}/public/images/jobsheet.png",

             :left_margin => 0, 
             :right_margin => 0, 
             :top_margin => 0, 
             :bottom_margin => 0, 
             :page_size => 'A4' }
end   end

person dannymcc    schedule 26.04.2010    source источник
comment
В сторону: Кесе? Нравится сыр по-немецки? :D   -  person ewall    schedule 26.04.2010


Ответы (2)


Я думаю, что ваши ассоциации с моделями неполны, основываясь на том, что вы разместили в своем вопросе:

class Kase < ActiveRecord::Base
  has_one :company
  has_many :people # Rails should handle the correct plural here
end

class Company < ActiveRecord::Base
  has_many :people
  belongs_to :kase
end

class Person < ActiveRecord::Base
  belongs_to :company
  belongs_to :kase
end

После правильной настройки ассоциаций вы можете получить доступ к атрибутам компании для данного дела:

kase.company.name
kase.company.mobile

или для данного лица:

person.company.name
person.company.mobile

В компанию можно попасть даже через кейс человека:

person.kase.company.name # etc...
person John Topley    schedule 26.04.2010
comment
Отлично, я внес эти изменения и сейчас попробую вызвать атрибуты. - person dannymcc; 26.04.2010
comment
Очевидно, я догадался, как называются атрибуты вашей модели, поэтому вам нужно использовать правильные имена, определенные в миграции вашей базы данных. - person John Topley; 26.04.2010
comment
Если я добавлю следующее: ‹li›Company: ‹span›‹%=h @kase.company.companyname %›‹/span›‹/li›, я получу следующую ошибку: NoMethodError in Kases#show Showing app/views/ kases/show.html.erb, где поднята строка №14: У вас есть нулевой объект, хотя вы этого не ожидали! Произошла ошибка при оценке nil.companyname Есть идеи, что я делаю неправильно? Спасибо, Дэнни. - person dannymcc; 26.04.2010
comment
Я предполагаю, что у вас действительно есть несколько дел с ассоциированной компанией в вашей базе данных, верно? Не могли бы вы отредактировать свой вопрос, чтобы показать нам действие show в вашем KasesController. - person John Topley; 26.04.2010
comment
Итак, по какой-то причине Rails говорит, что с вашим экземпляром @kase не связана компания. Можете ли вы попробовать запустить консоль Rails (script/console) и найти kase, у которого, как вы знаете, есть связанная компания, а затем посмотреть, что возвращает kase.company? - person John Topley; 26.04.2010
comment
Вот скриншот базы данных: img.skitch.com/20100426-pyi8uqks8ajs4mbjm43xe24gqn.jpg База данных находится только в разработке, поэтому есть только два тестовых примера/кейса. Оба показывают компанию в поле идентификатора компании. - person dannymcc; 26.04.2010
comment
Откуда взялось это поле company_id на скриншоте? Это фактический столбец в вашей таблице kases или результат выполнения запроса? - person John Topley; 26.04.2010
comment
На самом деле это столбец в таблице kases. Извините, если я что-то не так делаю - я действительно новичок в RoR - person dannymcc; 26.04.2010
comment
Если это поможет, все приложение находится на моей странице Github: github.com/dannyweb/surveycontrol - person dannymcc; 26.04.2010
comment
Завтра постараюсь глянуть. - person John Topley; 27.04.2010
comment
Глядя на код вашего контроллера на GitHub, кажется, что вы просто создаете отдельные экземпляры модели, а не создаете ассоциации между ними, что означает, что внешние ключи не устанавливаются в базе данных. Ознакомьтесь с разделами 4.1, 4.3.1.12 и 4.3.1.13 в guides.rubyonrails.org/association_basics.html. - person John Topley; 27.04.2010
comment
Спасибо, Джон. Я прочитал эти разделы, честно говоря, я думаю, что они меня немного смутили. Насколько я понимаю; Я добавил в соответствующие контроллеры has_many, own_to и т. д. Это основано на одном из примеров в Rails Wiki: class Supplier ‹ ActiveRecord::Base has_one :account, :include =› :representative end class Account ‹ ActiveRecord::Base принадлежит_к :supplier принадлежит_кому :representative end class Представитель ‹ ActiveRecord: :Base has_many :accounts end Нужно ли мне также добавлять class_names и т.д.? Спасибо, Дэнни. - person dannymcc; 27.04.2010
comment
@ Дэнни, структурные отношения между вашими моделями в порядке. Проблема в том, что когда ваши модели создаются и сохраняются в ваших контроллерах при запуске вашего приложения, вы также не устанавливаете ассоциации. По сути, экземпляры вашей модели — это одинокие острова, не имеющие отношения к другим моделям. Таким образом, внешние ключи никогда не устанавливаются в базе данных. Посмотрите на этот guides.rubyonrails.org/, в частности на строку @comment = @post.comments.build(params[:comment] в new действии CommentsController. - person John Topley; 27.04.2010
comment
ааа, хорошо, это немного помогает. Итак, для моего нового определения касе это будет что-то вроде этого:? @kase = @company.kaseid.build Для проекта, над которым я работаю, я должен попробовать и изучить Rails. Вы были бы заинтересованы в том, чтобы это работало на меня с комментариями в коде и взимало плату за ваше время? Спасибо, Дэнни. - person dannymcc; 27.04.2010
comment
Это на правильном пути, да. Или вы можете использовать create вместо build, чтобы создать ассоциацию и сохранить ее в базе данных за один шаг. Я ценю ваше предложение, но, к сожалению, в данный момент у меня не так много свободного времени. Я думаю, вы в любом случае получите больше прибыли, купив несколько или все эти скринкасты: pragprog.com/screencasts/v-rbar/everyday-active-record В PeepCode также есть много отличных скринкастов Rails: peepcode.com И продолжайте задавать вопросы здесь! Я бы хотел, чтобы Stack Overflow был рядом, когда я впервые изучал Rails. - person John Topley; 27.04.2010
comment
Хорошо, все равно спасибо. Я действительно ценю ваше время, хотя! Итак, если бы у меня было: @kase = @company.kaseid.create в моем контроллере kase, значит ли это, что при создании нового Kase добавить kaseid в модель компании? Я думаю, что это немного я не понимаю. Что эта линия на самом деле собирается делать. Спасибо, Дэнни. - person dannymcc; 27.04.2010
comment
Это должно быть @kase = @company.kases.create(params[:kase]) Все, что он делает, это создает новый случай через ассоциацию, т.е. добавляет новый случай в существующую коллекцию дел компании и сохраняет его в базе данных одним нажатием. С точки зрения базы данных, он устанавливает в столбце kase_id для этой записи компании идентификатор записи обращения, которому она принадлежит. Бит params[:kase] — это немного магии Rails, которая устанавливает атрибуты нового кейса в значения из отправленной формы. Вы можете протестировать его из консоли Rails, если хотите: @kase = @company.kases.create(:jobno => 'foo', :clientref => 'bar' etc.) - person John Topley; 27.04.2010
comment
Означает ли это, что, как у меня сейчас, каждая компания может иметь только один случай/Kase? - person dannymcc; 27.04.2010
comment
Вы объявили отношение один к одному между делом и компанией. - person John Topley; 27.04.2010
comment
Хм, я не уверен, что мне нужно объявить, поскольку в каждом случае есть только одна компания, но у каждой компании будет несколько дел. Так должно ли дело принадлежать компании, а компания имеет_много дел? - person dannymcc; 27.04.2010
comment
Хорошо, я внес все соответствующие изменения в модели (я думаю!) и добавил строку params, как указано выше, в kase_controller, но получаю следующую ошибку: NoMethodError in KasesController#new У вас есть нулевой объект, когда вы не ожидали Это! Произошла ошибка при оценке nil.kases - person dannymcc; 27.04.2010
comment
Извини, Дэнни, я больше не могу тратить время на то, чтобы помогать тебе в этом. Мой совет: купите себе хорошую книгу по Rails или скринкасты ActiveRecord, о которых я упоминал ранее. Удачи! - person John Topley; 27.04.2010
comment
Нет проблем, я покупаю эти скринкасты, пока мы говорим! Спасибо за вашу помощь, очень признателен! - person dannymcc; 27.04.2010

Если я правильно понимаю, ваш файл шоу будет содержать что-то вроде этого, чтобы показать номер мобильного телефона:

# in app/views/kases/show.html.erb
<h1><%=h kase.name %></h1>

<h2>Company Information</h2>
<ul>
  <li>Company Name: <%=h kase.company.name %></li>
  <li>Company Mobile: <%=h kase.company.mobile_phone %></li>
</ul>

Попробуй, посмотри, хватит ли этого.

person Joshua Pinter    schedule 26.04.2010
comment
К сожалению, это приводит к тому же сообщению об ошибке, что и выше. Спасибо хоть! - person dannymcc; 26.04.2010
comment
Используя весь приведенный выше код, Джон сказал: Если вы говорите kase :has_one company, тогда соединение основано на столбце kase_id в таблице компаний. Кроме того, вы используете названия компаний для значений идентификаторов. Это не правильно. Это рекордный номер компании, а не имена. Попробуй это. - person Joshua Pinter; 27.04.2010
comment
Первоначально это был просто идентификатор компании в виде чисел и т. д., но я изменил это, поскольку в раскрывающемся списке на странице нового обращения не отображались названия компаний, а только числовые значения. - person dannymcc; 27.04.2010