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>
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 %>
...