【问题标题】:rails 4 no data is being transferred to dbrails 4 没有数据传输到数据库
【发布时间】:2013-11-21 14:59:22
【问题描述】:

我正在尝试进行用户评论,当用户可以向另一个用户写评论时,我使用 :content 创建表评论,使用 :for_user_id 和 by_user_id 创建 user_reviews, 我的路线

devise_for :users
  resources :users, :only => [:show] do
    resources :reviews
  end

class Review < ActiveRecord::Base
    belongs_to :user
    has_many :users, :through => :users_reviews
end

class User < ActiveRecord::Base

  has_many :users_review
  has_many :reviews, :through => :users_review
end

class UsersReview < ActiveRecord::Base
  belongs_to :user
  belongs_to :review
end

class ReviewsController < ApplicationController

    def new
        @user = User.find(params[:user_id])
        @review = @user.reviews.new(params[:for_user_id])
    end

    def create
        @user = User.find(params[:id])
        @review = current_user.reviews.build(review_params)
        redirect_to root_path
    end

    def show
    end

    def index
        @user = User.find(params[:for_user_id])
        @reviews = Review.all
    end

    private
    def review_params
        params.require(:review).permit(:user_id, :user_id, :content)
    end

end

我的看法

<%= form_for([@user, @user.reviews.build]) do |f| %>
<%= f.text_area :content, placeholder: "Your review" %>
<%= f.submit "Go", class: "btn btn-large btn-primary" %>
<% end %>

一切正常,但没有数据发送到数据库:\我做错了什么?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4


    【解决方案1】:

    您没有在 create 方法中保存任何内容,因此不会持续存在任何内容。

    你会想要这样的东西:

    def create
      @user = User.find(params[:id])
      @review = @user.reviews.build(review_params)
    
      if @user.save && @review.save
        redirect_to root_path
      else
        (handle bad data)
      end
    end
    

    我也倾向于同意@marzapower - 如果您想使用current_user,则不需要@review 上面的行。我上面的方法包含了这个变化。

    【讨论】:

    • 是的,我发现了这个错误,但是当我修复它时,rails 将数据发送到评论表,并且不将数据发送到 users_review...users_review 为空
    • 查看我的编辑。您需要执行@user.save 来创建关联。见:stackoverflow.com/questions/12654040/…
    • 由于他使用&lt;%= form_for([@user, @user.reviews.build]) do |f| %&gt; 与特定用户,我怀疑真正的目标是current_user。这将是对嵌套资源路由的滥用。
    • @marzapower - 完全同意!
    【解决方案2】:

    您在 create 操作中缺少对 save 方法的调用:

    def create
         @user = User.find(params[:id])
         @review = current_user.reviews.build(review_params)
         @review.save
         redirect_to root_path
    end
    

    post 解释了构建和创建之间的区别。

    【讨论】:

    • 是的,我发现了这个错误,但是当我修复它时,rails 将数据发送到评论表,并且不将数据发送到 users_review...users_review 为空
    【解决方案3】:

    我认为您缺少两件事。 User 和 Review 类都需要引用它们在直通关系中使用的 UserReview 类,例如,

    class User < ActiveRecord::Base
      ...
      has_many :user_reviews_received, class_name: 'UserReview', foreign_key: :for_user_id
      has_many :reviews_received, through: :user_reviews_received, class_name: 'Review'
    
      has_many :user_reviews_written,  class_name: 'UserReview', foreign_key: :by_user_id
      has_many :reviews_written, through: :user_reviews_written, class_name: 'Review'
      ...
    end
    

    如上所述,create 操作似乎有点混乱。一般来说,在 new 和 create 操作中构建实例的参数应该是相同的,但你有一些不同之处。您可以通过以下两种方式之一解决此问题。一种选择是在控制器中解决它。

    class ReviewsController < ActionController::Base
      def new
        @user = User.find(params[:user_id])
        @review = @user.reviews_received.new(by_user_id: current_user.id)
      end
    
      def create
        @review = @user.reviews_received.create(params[:review].merge(by_user_id: current_user.id))
        redirect_to root_path
      end
    end
    

    第二个选项是在视图中解决它(表单中的新第一行)。

    <%= form_for([@user, @user.reviews_received.build(by_user_id: current_user.id)]) do |f| %>
      <%= f.hidden_field :by_user_id %>
      <%= f.text_area :content, placeholder: "Your review" %>
      <%= f.submit "Go", class: "btn btn-large btn-primary" %>
    <% end %>
    

    我倾向于第一个选项

    【讨论】:

    • 谢谢,但现在 rails 在 ReviewsController#create 未知属性中给出错误 ActiveRecord::UnknownAttributeError: for_user_id @review = @user.reviews.create(params[:review].merge(for_user_id: params[: for_user_id])) 我认为我所有的问题都在数据库中,在带有 for_user_id 和 by_user_id 的表 users_review 中
    • 我只能从你的帖子中推断出这么多,所以我只是试图获得新的并创建行动来同意。如果您在 Review 模型中有 by_user_id 和 for_user_id,那么让我们更新 User 模型以反映这一点。
    【解决方案4】:

    控制器有错误,我认为:

    def create
        @user = User.find(params[:id])
        @review = @user.reviews.build(review_params)
        @review.save
        redirect_to root_path
    end
    

    您正在为current_user 而不是@user 创建新的Reviews。

    【讨论】:

    • 我错过了包含save 方法,我的错。答案已更新。
    • 它可以工作,但 Rails 不会将数据发送到连接表 users_review
    • 其他表包含什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 2015-02-19
    • 2014-08-07
    • 2018-08-20
    • 1970-01-01
    相关资源
    最近更新 更多