将嵌套属性关联到用户

时间:2014-08-18 06:39:54

标签: ruby-on-rails

我正在尝试使用Rails 4.1构建一个小费用跟踪应用。使用设计进行授权。费用和它的嵌套属性,注释属于用户。在模型中设置关联,并且费用与用户相关联。这是费用控制器:

class ExpensesController < ApplicationController
    def new
        @expense = Expense.new
        @item = @expense.items.build
        #@comment = @expense.comments.build
    end

    def index
        @expenses = Expense.all
        #@items = Item.where(:expense_id => @expense.id)
    end

    def show
        @expense = Expense.find(params[:id])
        @items = Item.where(:expense_id => @expense.id)
    end

    def create
        @expense = current_user.expenses.new(expense_params)
        respond_to do |format|
            if @expense.save
                ExpenseMailer.expense_submission(@expense).deliver
                format.html { redirect_to @expense, notice: 'Expense Report Submitted.' }
                format.json { render :show, status: :created, location: @expense }
            else
                format.html { render :new }
                format.json { render json: @expense.errors, status: :unprocessable_entity }
            end
        end
    end

    def edit
        @expense = Expense.find(params[:id])
    end

    def update
        @expense = Expense.find(params[:id])
        #@comment = @expense.comments.build
        if @expense.update(expense_params)
            #if @comment.save
                #ExpenseMailer.comments_added(@expense).deliver
                flash[:notice] = "Expense Report Updated"
                redirect_to expenses_path
            #else
            #   flash[:notice] = "Expense Report Updated"
                #redirect_to expenses_path
            ##end
        else
            render 'edit'
        end
    end

构建注释属性的表单如下所示:

    <%= nested_form_for (@expense) do |f| %>
      <div class="form-group">
        <%= f.label :state %><br />
        <%= f.select :state, Expense.states, :include_blank => false, class: "form-control" %>
       </div>
       <%= f.fields_for :comments, @expense.comments.build do |comment| %>
        <div class="form-group">
          <%= comment.label :comment%>
          <%= comment.text_area :comment, class: "form-control" %>
        </div>
        <%= comment.hidden_field :commenter %>
      <% end %>
        <%= f.submit "Submit", class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

@ comment.commenter = current_user未将当前用户ID添加到数据库。我应该把它包含在费用控制器的某个地方吗?

2 个答案:

答案 0 :(得分:2)

你必须添加:

@comment.commenter = current_user

下面的if语句。像这样:

def create
  @article = Expense.find(params[:expense_id])

  if @comment = @expense.comments.create(comment_params)
    @comment.commenter = current_user
    @comment.save

    ExpenseMailer.comments_added(@expense).deliver
    redirect_to expenses_path
  end
end

然后再次保存评论。在当前代码中,您将使用新创建的对象覆盖@comment对象:

@comment = @expense.comments.create(comment_params)

但您还没有在任何地方设置commenter新对象。

答案 1 :(得分:0)

<强>模型

我只是尝试为您的strong params创建更好的代码,但我无法解决如何在您的嵌套属性中包含该参数

因此,我建议您使用Comment模型中的inverse_of:方法对其进行正确排序:

#app/models/expense.rb
Class Expense < ActiveRecord::Base
   belongs_to :user
   has_many :comments, inverse_of: :expense
   accepts_nested_attributes_for :comments
end

#app/models/comment.rb
Class Comment < ActiveRecord::Base
   belongs_to :expense, inverse_of: :comments
   before_create :populate_expense, on: :create

   private

   def populate_expense
      self.commenter_id = self.expense.user_id
   end
end

如果您正在填充accepts_nested_attributes_for指令

中的评论,这应该有效

<强>评论

我不明白为什么您为createexpenses控制器创建了两个comments操作 - 控制器操作意味着独立于Model

我想说的是,如果您认为comments#create属性创建会调用nested控制器操作,那么您会被误认为 - 只会调用它当您通过Rails路由器向它发送请求时:)

如果您分别创建CommentsExpenses,则可以使用这两种不同的操作;但他们不会被彼此援引。只有模型方法可以被控制器调用(你不应该调用其他控制器方法)

如果您想在Comment页面中创建expenses#show,请按以下步骤进行设置:

#config/routes.rb
resources :expenses do
   resources :comments #-> domain.com/expenses/:expense_id/comments/new
end

#app/controllers/expenses_controller.rb
Class CommentsController < ApplicationController
   def new
      @expense = Expense.find params[:expense_id]
      @comment = @expense.comments.new
   end

   def create
      @expense = Expense.find params[:expense_id]

      @comment = @expense.comments.new(comment_params)
      @comment.save
   end

   private

   def comment_params
       params.require(:comment).permit(:comment, :params).merge(commenter_id: current_user.id)
   end
end

如果您想从expenses#show页面创建评论,这将有效。如果您这样做,则需要确保调用comments#new / comments#create操作,而不是expenses控制器的操作