Adyl
Adyl

Reputation: 39

rails 4 no data is being transferred to db

I'm trying to do user reviews, when user can write review to another user, i create tables review with :content, user_reviews with :for_user_id, and by_user_id, my routes

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

and my view

<%= 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 %>

all work, but no data send to the db :\ what i doing wrong?

Upvotes: 0

Views: 87

Answers (4)

AndyV
AndyV

Reputation: 3741

I think you're missing two things. The User and Review classes both need to reference the UserReview class that they employ in the through relationship, e.g.,

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

As noted above, the create action seems a bit confused. Generally speaking the params should be the same for building up an instance in the new and create actions but you've got some differences. You could resolve this in one of two ways. One option would be to resolve it in the controller.

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

The second option would be to resolve it in the view (new first line in the form).

<%= 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 %>

I would tend towards something like the first option

Upvotes: 1

CDub
CDub

Reputation: 13354

You're not saving anything in the create method, therefore nothing is going to persist.

You'll want something like:

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

I would also tend to agree with @marzapower - If you want to use current_user, you don't need the line above @review. My method above has this change included.

Upvotes: 3

marzapower
marzapower

Reputation: 5611

There's an error in the controller, I think:

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

You were creating new Reviews for current_user instead of @user.

Upvotes: 0

AbM
AbM

Reputation: 7779

You are missing a call to the save method in your create action:

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

This post explains the difference between build and create.

Upvotes: 2

Related Questions