Domanda

I am completely new to Rails and still have a problem with sending parameters through this link from the ListaUsuarios View, despite trying and researching for many hours now:

<%= link_to "Agregar", @solicitud_contacto, method: :post %>

It does go to the create action as expected, since I have set

resources :solicitud_contactos

in the routes.rb. However I get the following error:

ActiveRecord::StatementInvalid in SolicitudContactosController#create

SQLite3::ConstraintException: solicitud_contactos.solicitante_id may not be NULL: INSERT INTO "solicitud_contactos" ("created_at", "solicitado_id", "solicitante_id", "updated_at") VALUES (?, ?, ?, ?)

Just to explain, since the question arose: SolicitudContacto is supposed to be a demand for adding another user ("friendship" or "contact" demand), so that the second user can then accept or reject the demand. So I simply want to save such a demand in the database when somebody clicks on the link. "Usuario" (attribute type in the "SolicitudContacto" model) simply means "User".

Also, the way I get it, the following link should get an equivalent result:

<%= link_to "Agregar", solicitud_contacto_path(@solicitud_contacto), method: :post %>

but it gets me a different error. Apparently here the ids are transferred, but the link goes to the show action instead.

Routing Error

No route matches {:action=>"show", :controller=>"solicitud_contactos", :id=>#<SolicitudContacto id: nil, solicitante_id: 2, solicitado_id: 4, created_at: nil, updated_at: nil>}

I get the same problem with the

<%= link_to "Rechazar", @solicitud_contacto, :method => :delete %>

in the same view.

edit: Thanks to Baldricks comment at least the delete link now works, I did not remember that I have to use an actual object from the database. So replacing the corresponding if block by the following does the work:

  <% if (index = @solicitantes.index { |solic| solic.solicitante.id == usuario.id }) != nil %>
    <%= link_to "Rechazar", @solicitantes[index], :method => :delete %>

The @solicitud_contacto object with the corresponding ids for

@solicitud_contacto.solicitante.id @solicitud_contacto.solicitado.id

are definitely set though as I have them printed out in the same view for testing. I hope someone can help me, because this has really been kind of frustrating... Thanks a lot!

P.S.:

I also read that this:

<%= javascript_include_tag "application" %>

should be set in the application.html.erb. It is!

Here ist the relevant code:

SolicitudContacto Model

class SolicitudContacto < ActiveRecord::Base
  attr_accessible :solicitado_id, :solicitante_id
  belongs_to :solicitado, class_name: "Usuario"
  belongs_to :solicitante, class_name: "Usuario"
end

SolicitudContacto Controller

class SolicitudContactosController < ApplicationController
  def create
    @solicitud = SolicitudContacto.new(params[:solicitud_contacto])
    @solicitud.save
    redirect_to :controller => SearchUsersController, :action => BusquedaUsuarios
  end

  def destroy
    @solicitud = SolicitudContacto.find(params[:id])
    @solicitud.destroy
    redirect_to :controller => SearchUsersController, :action => BusquedaUsuarios
  end

  def index
    @solicitudes = SolicitudContacto.all
  end

  def new
  end

  def show
    @solicitud = SolicitudContacto.find(params[:id])
  end
end

SearchUsersController

class SearchUsersController < ApplicationController

  def BusquedaUsuarios
    @usuario = Usuario.new
  end

  def ListaUsuarios
    # DELETE!!!!!
    $current_usuario = Usuario.find(2)

    @cur_usuario = $current_usuario;
    @solicitud_contacto = SolicitudContacto.new
    @usuario = Usuario.new(params[:usuario])
    @filtros = Hash.new(0);
    if @usuario.nombre != ""
    @filtros["nombre"] = @usuario.nombre
    end
    if @usuario.apellido != ""
    @filtros["apellido"] = @usuario.apellido
    end
    if @usuario.email != ""
    @filtros["email"] = @usuario.email
    end
    @solicitados = @cur_usuario.solicitantes
    @solicitantes = @cur_usuario.solicitados
    @contactos = @cur_usuario.user1s + @cur_usuario.user2s
    @usuarios = Usuario.where(@filtros).order(:nombre).all
  end
end

ListaUsuarios (User List View of the SearchUsersController)

<h1>SearchUsers#ListaUsuarios</h1>
<p>Find me in app/views/search_users/ListaUsuarios.html.erb</p>

<table>
  <tr>
    <th>Nombre</th>
    <th>Apellido</th>
    <th>Email</th>
    <th></th>
  </tr>

  <% @usuarios.each do |usuario| %>
    <tr>
      <td><%= usuario.nombre %></td>
      <td><%= usuario.apellido %></td>
      <td><%= usuario.email %></td>
      <td>
      <% @solicitud_contacto.solicitante = @cur_usuario %>
      <% @solicitud_contacto.solicitado = usuario %>
    <br>
      <%= @solicitud_contacto.solicitante.id %>
      <%= @solicitud_contacto.solicitado.id %>
    <br>
      <!-- responder la solicitud -->
      <% if @solicitantes.index { |solic| solic.solicitante.id == usuario.id } != nil %>
        <%= link_to "Rechazar", @solicitud_contacto, :method => :delete %>
      <!-- solicitud ya fue mandada -->
      <% elsif @solicitados.index { |solic| solic.solicitado.id == usuario.id } != nil %>
        Esperando Respuesta
      <!-- solicitar contacto -->
      <% else %>
        <%= link_to "Agregar", @solicitud_contacto, method: :post %>
      <% end %>
      </td>
    </tr>
  <% end %>
</table>
È stato utile?

Soluzione

When you create a link to the show or delete action, you must do it with a persisted object (i.e. an object an object with an ID created in the DB). In the controller you're doing

@solicitud_contacto = SolicitudContacto.new

The object is instantiated, but is not created in the DB (you must call save or create for this). It has no ID.

How to solve your problem ? I'm not sure, I don't understand what you're trying to achieve. I think the link to target is wrong, it should be @solicitud_contacto.solicitante

<% if @solicitantes.any? { |solic| solic.id == usuario.id }  %>
    <%= link_to "Rechazar", @solicitud_contacto.solicitante, :method => :delete %>
...
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top