lundi 15 janvier 2018

Validate uniqueness of a value with scope - Ruby on Rails 5

I have table posts with a model Post and table languages (columns - id, post_id, language) with a model Language. Post has many languages and Language belongs to a Post. In the post model I have:

has_many :languages
validates_associated :languages

Language model:

belongs_to :post
validates_uniqueness_of :language, scope: :post_id

language is the column in the table languages.

The language field is allowed in the posts_controller (strong parameters):

def post_params
    params.require(:post).permit(:languages_attributes => [:language], ...)

This is the view for the form for creating a post:

<%= form_for @post do |f| %>
    .....
    <%= f.fields_for :languages do |language| %>
        <%=language.select :language, ['english', 'italian', 'french', 'spanish'] %>
    <% end %>

This select element can be cloned up to 4 times via JS and user can add more than 1 language. The generated HTML for this select is:

<select name="post[languages_attributes][0][language]" id="post_languages_attributes_0_language">
    <option value="english">english</option>
    <option value="italian">italian</option>
    <option value="french">french</option>
    <option value="spanish">spanish</option>
</select>

When user clicks on the button and another select is created, it is with name post[languages_attributes][counter++][language] and everything works fine.

This is create post method:

@post= Post.new(post_params)
if @post.save
....

I want to validate uniqueness of the languages with scope of the current post (scope: :post_id) and every post to have only 1 time English language for the example. The post can have more than 1 languages.

I tried with validates_uniqueness_of :language, scope: :post_id, but if I add two times English (all lowercase), there is no error for this and the data is inserted to the tables.

How to validate uniqueness of the languages for a post with the scope of the current post ?

Aucun commentaire:

Enregistrer un commentaire