0

You'll see in my code I've got a "has_many => belongs_to" models association and a nested form in the new actions's view.

Plus, I've used Using two separate fields for the same parameter in a Rails form handler?

The problem is the "prix" attribute (in the "Projet" model) is recorded in the database, but not the "nom" attribute (in the "Activite" model).

Maybe the problem is around the strong parameters, but I thinks it's all good in my code... Or maybe in the code I've found on the other Stackoverflow question I've linked.

There is french words in my code : activite is activity, projet is project, nom is name, prix is price, very easy :)

Thank's for your help !

app/model/projet.rb :

class Projet < ActiveRecord::Base

    has_many :activites

    accepts_nested_attributes_for :activites,
    reject_if: lambda {|attributes| attributes['nom'].blank?}

end

app/models/activite.rb :

class Activite < ActiveRecord::Base

    belongs_to :projet

    def acttext=(value)
      @acttext = value if value
      prepare_act
    end

  def actselect=(value)
    @actselect = value if value
    prepare_act
  end

  def acttext
    @acttext || self.nom
  end

  def actselect
    @actselect || self.nom
  end

private 
  def prepare_act
    self.nom = acttext if acttext
    self.nom = actselect if actselect
  end

end

app/controllers/projets_controller.rb :

class ProjetsController < ApplicationController

    def new
        @projet = Projet.new
        @activites_options = Activite.pluck(:nom).uniq
        2.times { @projet.activites.new}
    end

    def create
        @projet = Projet.new(projet_params)

        if @projet.save
          redirect_to @projet
        else
          render 'new'
        end
    end

  private

    def projet_params
      params.require(:projet).permit(:prix, activites_attributes: [:id, :nom, :heures, :minutes, :acttext, :actselect])
    end
end

app/views/projets/new.html.erb :

<div>
    <%= form_for @projet do |f| %>    
    <%= f.label :prix %><br> 
    <%= f.text_area :prix %><br>
            <ul>
              <%= f.fields_for :activites do |activites_form| %>
                <li>
                  <%= activites_form.label :choisissez_un_type_dactivité %>
                  <%= activites_form.select :actselect, @activites_options, {include_blank: true} %>

                  <%= activites_form.label :ou_créez_en_un_nouveau %>
                  <%= activites_form.text_field :acttext %><br>

                  <%= activites_form.label :heures %>
                  <%= activites_form.text_field :heures %>

                  <%= activites_form.label :minutes %>
                  <%= activites_form.text_field :minutes %>
                </li>
                <br>
              <% end %>
            </ul>
    <p><%= f.submit "Créer le projet" %></p>
    <% end %>
    </div>
Community
  • 1
  • 1
Hugololo
  • 3
  • 2

1 Answers1

0

In order for virtual attributes to work, you'll also need to define a setter and a getter. This can be done by either defining the getters and setters explicitly yourself or by using attr_accessor.

Example using attr_accessor:

class Activite < ActiveRecord::Base
  attr_accessor :nom
  ....

end

Example defining both setter and getter manually:

class Activite < ActiveRecord::Base
  ....

  def nom=(value)
    super
  end

  def nom
    @nom
  end
end

For the second issue with your class naming due to them being French, you'd also want specify the class_name option on both has_many and belongs_to to specify your non english class names as follows:

class Projet < ActiveRecord::Base
  has_many :activites, class_name: 'Activite'
end

Similarly, for Activite model:

class Activite < ActiveRecord::Base
  belongs_to :projet, class_name: 'Projet'
end
vee
  • 38,255
  • 7
  • 74
  • 78
  • Thanks for the informations about the two ways of defining virtual attributes, but that's already OK in my code, isn't it ? And for the class naming, there isn't any problem with it because the pluralization of "Activite" and "Projet" is working. However, I've test your suggestion, but it didn't solve the problem : the 'nom' attribute is not recorded, and I've not any errors. – Hugololo Jul 30 '15 at 13:47
  • Have you inspected the `params` hash? If you can verify that `nom` attribute has value in the params hash, then the problem is elsewhere. – vee Jul 30 '15 at 13:52
  • Okay, I've looked at the rails webrick : in the params hash, there is all the things that I've put in the forms, and the "acttext" ant "actselect" are here, so it's ok. But just after in the SQL request, there is just an "insert into" request on the "projets" table, nothing on the "activites", it seems like the problem...? – Hugololo Jul 30 '15 at 14:21
  • 1
    Found ! It was 'accepts_nested_attributes_for :activites, reject_if: lambda {|attributes| attributes['nom'].blank?}'. I've removed the "reject if" line, and now that's work. I hadn't display this line in the question in order to simplify... – Hugololo Jul 30 '15 at 14:49