form_for for relation table with type of many to many relation

947 views Asked by At

My goal is to display select box for each relation for users and specific project. All users need to be listed but only project users have some type of relation. Other users have none selected in theirs select box.

I have this model:

class Project < ActiveRecord::Base
    belongs_to :company
    has_many :tasks, :order => 'state_type_id ASC'

    has_many :project_user_relations
    has_many :users, :through => :project_user_relations

    def t_name
       name.camelcase
    end
end

class User < ActiveRecord::Base
    belongs_to :company

    has_many :tasks , :foreign_key => :assigned_user_id 

    has_many :project_user_relations
    has_many :projects, :through => :project_user_relations

    def full_name
     firstname + ' ' + lastname
    end

    def relation_to(project)
     relation=ProjectUserRelation.find_by_project_id_and_user_id(project.id, id)
     relation ||= relation=ProjectUserRelation.new
    end
end

class ProjectUserRelation < ActiveRecord::Base
    belongs_to :project
    belongs_to :user
    has_one :project_user_relation_type
end

class ProjectUserRelationType < ActiveRecord::Base
    def t_name
        I18n.t("app.projects.users.relation.type."+code)
    end
end

I want make a form to display all users, with collection_select. I used code:

def edit_all
   @project = Project.find(params[:project_id])
   @users = User.all
....

in my controler routes works ok.

in my view:

<% @users.each do |user| %>
   <%= f.fields_for :users, user do |user_fields| %>
     <tr class="reference" rel="<%=  parent_user_path(user)  %>" >
        <td class="name"><%= link_to user.full_name, parent_user_path(user) %></td>
        <td class="email"><%= mail_to user.email %></td>
        <td class="type">
            <%= user_fields.fields_for user.relation_to @project do |relation_fields| %>
                <%= relation_fields.collection_select :project_user_relation_type, ProjectUserRelationType.all, :id, :t_name, {:include_blank => false, :prompt => t("helpers.select.prompt") } %>
            <%  end %>
         </td>
      </tr>
   <% end %>      
<% end %>     

or for test:

<%= f.fields_for :users, @users do |xuser_fields| %>
    <% logger.debug "#{self.to_s} xuser_fields = #{xuser_fields.object.inspect} ;" %>
    <tr>
       <td><%= xuser_fields.text_field :firstname %></td>
       <td></td>
       <td></td>
       <td></td>
    </tr>
<% end %>

but notnihng woks right

first one generates wrong name in html:

select id="project_users_project_user_relation_project_user_relation_type" name="project[users][project_user_relation][project_user_relation_type]"

second one generates error: undefined method `firstname' for # Array:0x4d03658

Can you help me to solve this situation.

PS:sorry for long code :(


SOLUTION (probably - solved by reading RoR sources)

I found sollution i thing.

A method

def name_attributes=(attributes)
    # Process the attributes hash
end

in Project model was missing.

It is unbelievable sollution :]. There is also exact syntax after fields_for: :name, @some_collection, where name must be exactly same name as in the beginign of mentioned def in Model.

0

There are 0 answers