使用has_many关联保存模型

时间:2012-11-30 22:56:50

标签: ruby-on-rails ruby ruby-on-rails-3

我正在为学校建立一个评审申请表。用户只有在登录后才能查看学校。

您现在可以做些什么:

您可以撰写评论并在1 - 5之间添加评分。该应用程序会保存评论。

我想要它做什么:

我想保存记录的user_id。因此,评论属于用户和学校。

但我对如何做到这一点感到困惑。欢迎任何想法和指南=)

审核模式:

class Review < ActiveRecord::Base
  belongs_to :school
  belongs_to :user
  attr_accessible :content, :rating
end

学校模式:

class School < ActiveRecord::Base
  has_many :reviews
  ..more code..
end

用户模型:

class User < ActiveRecord::Base  
  has_many :reviews
  ...more code..
end

审核控制器:

class ReviewsController < ApplicationController
    def create
        @school = School.find(params[:school_id])
        @review = @school.reviews.create!(params[:review])
        redirect_to @review.school, notice: "Review has been created."
    end
end

审核表

<%= form_for [@school, Review.new] do |f| %>
        <h3>Write a review</h3>
        <div class="reviews_comments_container">
            <div class="review_box">
                <ol class="radio-rater">
                    <%= f.radio_button(:rating, 1) %>
                    <%= f.radio_button(:rating, 2) %>
                    <%= f.radio_button(:rating, 3) %>
                    <%= f.radio_button(:rating, 4) %>
                    <%= f.radio_button(:rating, 5) %>
                </ol>
            </div>
            <div class="review_box" id="review_textarea">
                <%= f.text_area :content, rows: 4, cols: 70 %>
            </div>
            <div class="review_box">
                <%= f.submit 'Save your review', :class => "btn" %>
            </div>
        </div>
    <% end %>

迁移文件:

class CreateReviews < ActiveRecord::Migration
  def change
    create_table :reviews do |t|
      t.text :content
      t.integer :rating
      t.belongs_to :school
      t.belongs_to :user
      t.timestamps
    end
    add_index :reviews, [:school_id, :user_id]
  end
end

2 个答案:

答案 0 :(得分:0)

如果您使用Devise对用户进行身份验证,则current_user是在身份验证后返回的对象。在你的ReviewsController中:

class ReviewsController < ApplicationController
  def create
    @school = School.find(params[:school_id])

    @review = @school.reviews.build(params[:review])
    @review.user_id = current_user

      if @review.save
    redirect_to @review.school, notice: "Review has been created."
       end
  end
end

如果你必须在表'reviews'中包含一个名为user_id的新列,那么你应该创建一个新的迁移,然后'rake db:migrate'。 (根据你的迁移,你似乎有这个专栏。)

编辑:嵌套资源的路由:

resources :schools do
  resources :reviews do
end

答案 1 :(得分:0)

有几种不同的方法可以做到这一点。您已正确设置了关联,因此它归结为您的控制器。由于:school_id来电的方式,您的create已设置:

@review = @school.reviews.create!(params[:review])

您可以手动设置:user_id

params[:review][:user_id] = current_user.id
@review = @school.reviews.create!(params[:review])

假设您的登录系统中有current_user方法,这是相当标准的。您的创建操作可能会有所改进。尝试这样的事情:

def create
    @school = School.find(params[:school_id])
    @review = @school.reviews.new(params[:review])

    #Assuming your authentication provides the current_user method
    @review.user_id = current_user.id

    if @review.save
        redirect_to @review.school, notice: "Review has been created."
    else
        render :new
    end
end

如果验证失败或由于某种原因无法将记录保存到数据库,那么可以更好地控制错误处理。此外,您应该在new中执行reviews_controller操作,这将使其如下所示:

class ReviewsController < ApplicationController
    def new
        @school = School.find_by_id(params[:school_id])
        @review = Review.new
    end

    def create
        @school = School.find(params[:school_id])
        @review = @school.reviews.new(params[:review])

        #Assuming your authentication provides the current_user method
        @review.user_id = current_user.id

        if @review.save
            redirect_to @review.school, notice: "Review has been created."
        else
            render :new
        end
    end
end

这样,在form_for来电中,您可以将Review.new来电更改为@review,这样会更好。

<强>更新

抱歉,我的错误。如this SO answer shows,可以将Review.new放在form_for标记中。这对我来说似乎有些不好,但我在几个地方证实了这一点。