0

I'm unsuccessfully trying to update a submodel, somehow nested but getting unusual results.

Background (Scroll down for problem):

Update a boolean verified of a reviews model to associate whether a translation is verified or not, with translation entry and user model associated references. Details about creating a verification are here

# routes.rb
resources :entries do
   resources :reviews
end


# entry.rb
belongs_to :user
has_one :review
accepts_nested_attributes_for :review


# user.rb
has_many :entries
has_many :reviews


# review.rb
belongs_to :user
belongs_to :entry

From entry index, pass the entry instance to the edit partial, works perfect

# /entries/index.html.erb
<% @entries.each do |entry| %>
   ...
   <% if entry.review %>
      <%= render 'reviews/edit', entry: entry %>
   <% end %>
   ...
<% end %>

The _edit.html.erb form seems correct...

# reviews/_edit.html.erb
<span>
  <%= form_for([entry, entry.review]) do |f| %>
    <div class="form-check form-switch">
      <%= f.check_box :verified, class: "form-check-input" %>
    </div>
    <%= f.submit class: "btn btn-primary"%>
  <% end %>
</span>

In the browser console, the model entry is well assigned. And also the association entry.review is well assigned i.e

>> entry.review
=> #<Review id: 4, user_id: 1, entry_id: 19, 
     verified: false, created_at: "2021-02-18 03:43:27", 
     updated_at: "2021-02-18 14:31:15">

Even using the Ruby on Rails 6 deprecated method update_attribute works

>> entry.review.update_attribute(:verified, false)
=> true

Problem: The update method in reviews_controller.rb executes successfully when verified is true, but not when it's false

# reviews_controller.rb
def update
   @entry.review.update(review_params)
end

private

def review_params
   params.require(:review).permit(:verified, user: current_user, entry: @entry)
end

Works

{"_method"=>"patch", "authenticity_token"=>"...", 
"review"=>{"verified"=>"1"}, "commit"=>"Update Review"}

Working

but not

{"_method"=>"patch", "authenticity_token"=>"...", 
"review"=>{"verified"=>"0"}, "commit"=>"Update Review"}

not Working

axelmukwena
  • 779
  • 7
  • 24

1 Answers1

0

I think I found the problem after @yzalavin suggestion. Somehow validations were preventing the update. I do not know the association yet.

Simply adding on: :create allowed me o update.

validates_presence_of :entry_id, :user_id, :verified, on: :create
axelmukwena
  • 779
  • 7
  • 24
  • Ah yes. Presence validator fails when the `verified.blank?` returns `true`. Generally speaking, it should not be used for boolean values. Even as written now your create won't work with `verified: false`. For boolean columns use `validates :verified, inclusion: { in: [true, false] }` instead – BroiSatse Feb 19 '21 at 10:05
  • So what you mean is `:verified => false` makes `verified.blank?` return true? Do you think it'll be smart just to use an integer column and work with `0` and `1` instead of a boolean type? – axelmukwena Feb 19 '21 at 10:15
  • 1
    Ah, no, boolean columns should be used whenever it makes sense and it does make sense here. It is just that this particular validator won't work. I assume you want to test that it is not being set to nil, in which case inclusion validator is your friend. However, to be honest, best option is to set the column to non-nullable in the database and no validation is then required. – BroiSatse Feb 19 '21 at 10:18
  • Ah okay then. I'll try to adopt the non-nullable practice. Otherwise thanks for the input – axelmukwena Feb 19 '21 at 10:21