2015-09-08 3 views
0

Я привык к MySQL, но сейчас пытаюсь использовать Ruby on Rails. В MySQL у меня было бы две таблицы, одна из которых содержала бы ссылку на другую («сообщения», ссылающиеся на «тему»). Запрос MySQL, выполняющий то, что я хочу, будет похож на «SELECT * FROM Posts WHERE posts.topic =« topic »(« тема »здесь - переменная).Интерфейс базы данных Ruby on rails

Однако, пытаясь работать с моделью Ruby, у меня есть . спутать переменные передается между контроллером и видом являются недействительными, поскольку они пустые таблицы

в мой контроллер:.

def topic 
    @topic = Topic.where(params[:topic]) 
    @posts = Post.where(topic: @topic.object_id) 
end 

Я не знаю, как выбрать сообщения, которые имеют определенную тему переменная «тема».

На вид:

<% @posts.each do |post| %> 
    <p><%= post.title %></p> 
<% end %> 

Миграционные файлы:

class CreatePosts < ActiveRecord::Migration 
    def change 
    create_table :posts do |t| 
     t.string :title 
     t.string :text 
     t.references :topic 
     t.timestamps 
    end 
    end 
end 
class CreateTopics < ActiveRecord::Migration 
    def change 
    create_table :topics do |t| 
     t.string :topic 
     t.timestamps 
    end 
    end 
end 

ответ

1

Учитывая, что сообщение и тему связаны, в соответствии с вашими миграции, по крайней мере, в моделях вы должны быть о том,»

class Topic 
    has_many :posts 

и

class Post 
    belongs_to :topic 

Учитывая, что у Вас тогда есть экземпляр Тема, @topic, вы можете получить все связанные записи с:

@posts = @topic.posts 
0

Я думаю, что те методы, которые вы положить в ваш контроллер в порядке, где они есть, но имейте в виду, что путь Rails является «жира моделей, исхудавшие контроллеры.» Если вы поместите эту логику в модель как метод, ее гораздо легче читать в контроллере. Кроме того, вы должны посмотреть в scopes, так как они помогут вам с подобными запросами в строке.

В любом случае, вы должны придерживаться следующих в вашей теме модели:

scope :by_name, ->(name) { where(topic: name) } 

Это по сути то же самое, выполнив следующие действия:

def self.by_name(name) 
    where(topic: name) 
end 

На модели сообщений, вы бы в состоянии сделать следующее:

scope :by_topic, ->(topic) { where(topic_id: topic) } 

Другая проблема с тем, что вы застряли в контроллере, - это t когда вы используете области действия или «где», он возвращает массив, содержащий все разные записи, соответствующие вашим условиям запроса. Итак, когда вы вызываете @topic = Topic.where (params [: topic]), вы возвращаете массив объектов. Поэтому, когда вы делаете @ topic.id, вы пытаетесь вернуть идентификатор массива вместо одного объекта.

Исходя от того, что я показал вам раньше, это делает гораздо больше смысла для вас, чтобы сделать это:

def topic 
    @topic = Topic.by_name(params[:topic]).first #this returns the first record 
    @post = Post.by_topic(@topic.id) 
end 

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

0

Хорошо, сначала a primer о том, как работает дизайн базы данных и как работает Rails (действительно, ActiveRecord). В принципе, вы должны подключать posts.topic_id = topic.id, а не posts.topic = topic.topic.

Ваша миграция верна как есть, create_table автоматически включает столбец: id PRIMARY KEY. Тем не менее, вы должны знать, что они эквивалентны:

t.references :topic 
t.belongs_to :topic 
t.integer :topic_id 

На ваш взгляд, вместо внедрения topic.topic и мимоходом, что к контроллеру, когда форма представляется, встраивать topic.id (documentation for the select helper имеет хороший пример этого) и в вашем контроллере:

@topic = Topic.find params[:id] 
@posts = @topic.posts 
Смежные вопросы