Build vs new in Rails 4

My question is similar to Build vs new in Rails 3 .

In Rails 3, I could create an object in a view to verify authorization through cancan.

<% if can? :create, @question.answers.new %> # Code... <% end %> 

In Rails 3, the difference between .new and .build was that .build added the newly created object to the parent collection, which led to an extra record in the view, which was clearly not desirable.

In Rails 4, however, both add an object to the collection, creating an empty entry in the view.

Does anyone have any tips on how to solve this? Verifying that the .persisted? entry .persisted? in the view would be an option, but somehow I feel like I don't need to do this.

Edit: To clarify, the CanCan model looks like this:

 can :manage, Answer do |answer| user.belongables.include?(answer.question.try(:belongable)) end 

Because of this, I cannot just check the class. The actual instance is really necessary for comparison based on the relationship.

+7
activerecord ruby-on-rails-4
source share
2 answers

I could solve the problem and find out two ways.

First, as https://github.com/rails/rails/issues/9167 points out, using scoped allows this. So instead I use @question.answers.scoped.new . As I explained, the simple Answer.new(question: @question) failed because it took more data and the example was simplified.

Secondly, holding the MVC pattern. The controller is responsible for preparing the data. So, when you go over these issues, you are preparing data in your controller, for example @answers = @question.answers . The @answers collection @answers does not affect .new or .build on the association.

+2
source share

I am not completely updating in CanCan, but if the ability to create is not tied to a specific instance of @question in CanCan, it looks like you can directly check authorization against the class. No instance should be built, and in your view there is no extraneous object.

 <% if can? :create, Answer %> # Code.. <% end %> 

https://github.com/ryanb/cancan/wiki/Checking-Abilities#checking-with-class

EDIT:

Based on editing, try creating an autonomous answer with an association to a question that interests you.

 <% if can? :create, Answer.new(question: @question) %> # Code.. <% end %> 

this should not at least add an instance of Answer to the @question.answers collection.

+4
source share

All Articles