2015-03-16 3 views
0

Я изучаю Rails (4.2 установлен) и работаю в приложении для моделирования социальной сети. У меня настроено отношение «один к многим» между пользователями и сообщениями, и теперь я пытаюсь добавить также комментарии к сообщениям. После нескольких попыток и после documentation on rubyonrails.org я закончил с следующей установкой:Ruby on Rails - вложенные ассоциации - создание новых записей

Модель пользователя

has_many :posts, dependent: :destroy 
    has_many :comments, through: :posts 

Сообщение Модель

belongs_to :user 
    has_many :comments 

комментарий модель

belongs_to :user 

Комментарий начинается с показа страницы сообщение, поэтому Сообщение Контроллер имеет:

def show 
    @comment = Comment.new 
    end 

Теперь вопрос: в Комментарии Controller, что такое правильный способ создать новый запись. Я пробовал ниже и многие другие, но безуспешно.

def create 

    @comment = current_user.posts.comment.new(comment_params) 
    @comment.save 

    redirect_to users_path 

    end 

(current_user от Завещания)

Кроме того, после этого, как я могу выбрать пост, соответствующий комментарий?

Спасибо

+0

'current_user.posts' представляет собой набор сообщений. Ассоциация 'has_many' находится на одном посту, а не на собрании. (Редактировать: я должен был представить как ответ.) –

ответ

0

Вы хотите создать отношения на Post, позволяя каждому Comment знать «который Post это относится к.» В вашем случае вы, скорее всего, захотите создать внешний ключ на Comment для post_id, тогда каждый Comment будет belong_to конкретным Post. Итак, вы добавите belongs_to :post на свою модель Comment.

Итак, ваши модели:

class User < ActiveRecord::Base 
    has_many :posts, dependent: :destroy 
    has_many :comments, through: :posts 
end 

class Post < ActiveRecord::Base 
    belongs_to :user 
    has_many :comments 
end 

class Comments < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :post 
end 

Затем, чтобы создать Comment, вы хотели бы сделать одну из двух вещей в вашем контроллере:

  1. Загрузите Post, соответствующим Comment, который вы создаете через URI в качестве параметра.

  2. Передайте Post ID в форме, в которой называет метод create на Comment.

Я лично предпочитаю загрузку Post от параметра в URI, как вы будете иметь меньше проверку сделать, насколько для авторизации может Comment в вопросе быть добавлен к Post - например, подумайте о том, кто-то взломал форму и изменил идентификатор для Post, который изначально задает форма.

Тогда ваш метод create в CommentsController будет выглядеть следующим образом:

def create 
    @post = Post.find(post_id_param) 

    # You'll want authorization logic here for 
    # "can the current_user create a Comment 
    # for this Post", and perhaps "is there a current_user?" 

    @comment = @post.comments.build(comment_params) 

    if @comment.save 
    redirect_to posts_path(@post) 
    else 
    # Display errors and return to the comment 
    @errors = @comment.errors 
    render :new 
    end 
end 


private 

def post_id_param 
    params.require(:post_id) 
end 

def comment_params 
    params.require(:comment).permit(...) # permit acceptable Comment params here 
end 
+0

Большое спасибо! действительно подробный и профессиональный ответ. Просто чтобы убедиться, что я получил это право: 1. Правильно ли это передать параметр в URL с помощью simple_form? 'simple_form_for (@comment, url: comments_path (@comment, post_id: @ post.id)) do | f |' 2. в CommentsController, перед @ comment.save, мне пришлось добавить пользователя, иначе не будет спасти. Это верно? '@comment = @ post.comments.build (comment_params) @ comment.user = current_user' Еще раз спасибо! – iacobSon

+0

Да, это звучит правильно. Я не использовал simple_form, но считаю, что это правильно. – CDub

0

Изменить Comment модель в:

class Comment < ActiveRecord::Base 
    belongs_to :post 
    belongs_to :user, through: :post 
end 

Пропустите post_id из шаблона вида:

<%= hidden_field_tag 'post_id', @post.id %>

Затем измените create действие:

def create 
    @post = Post.find(params[:post_id]) 
    @comment = @post.comments.build(comment_params) 
    @comment.user = current_user 
    redirect_to post_path(@post) 
end 
Смежные вопросы