Ruby on Rails 4 find object by id

I have the following show-view where I display basic product information and display other products to users.

<h1>Book <%= @product.name %></h1>
<% @products.each do |product| %>
<ul>
    <%= product.name %>
    <%= link_to "Make offer", {controller: "offers", :action => 'create', id: product.id }    %>
</ul>

      

controller

def show
    @product = current_user.products.find(params[:id])
    @products = Product.all
end

      

My goal is to make an Offer between two Products. I created a proposal model and methods for creating a proposal:

class Offer < ActiveRecord::Base
  belongs_to :product

  belongs_to :exchanger, class_name: "Product", foreign_key: "exchanger_id" 

  validates :product_id, :exchanger_id, presence: true

  def self.request(product, exchanger)
    unless product == exchanger or Offer.exists?(product, exchanger)
    transaction do
      create(product: product, exchanger: exchanger, status: "oczekujace")
      create(product: exchanger, exchanger: product, status: "oferta")
    end
  end
  #other methods 
end

      

Making suggestions works because I checked it in the console. My problem is OfferController:

class OffersController < ApplicationController
 before_filter :setup_products

 def create
   Offer.request(@prod, @exchanger)
   redirect_to root_path
 end

 private

 def setup_products
   @prod = current_user.products.find(1)
   @exchanger = Product.find_by_id(params[:id])
 end
end

      

The problem is with the following line (using the link on the show page for products with a different id than 1 job):

@prod = current_user.products.find(1)

      

But I don't know how to find the object in Db for the actual product that my show page is showing. Not only for id = 1.

+3


source to share


1 answer


I don't know how to find this object in the database.

I don't know a specific answer to your question, but maybe if I explain what you need to look at your solution will arise:


To find

Rails is not magic - it uses ActiveRecord (which is ORM - Object-Relation Mapper

), which means every time you run a query (via find

), your ORM (ActiveRecord) will look for the corresponding database data for you

The problem is that while you are using the correct syntax to search for, you might not be recording id

of 1

your db.

current_user.products.find(1)

tells ActiveRecord about the reach of the request around the current user and their products. So you end up with something like this:

SELECT * FROM 'products' WHERE user_id = '15' AND id = '1'


Objects

Also, you have to remember that Ruby (and Rails due to the fact that it is built in Ruby) is a language object orientated

. This means that whatever you load / interact with in the language must be object based

The problem is that you are not binding your object to your Rails framework correctly. What I mean here is described below, but essentially if you build your Rails framework correctly it will give you the ability to link your objects to each other, allowing you to call the various products

you need fromoffer

This is an easy way to look at it, of course. You want to look at this diagram to see how it works:

enter image description here

Bottom line - try treating your application as a series of objects rather than a logical flow. This will help you appreciate the various associations, etc., that you need to move forward.




Resources

You mentioned that you cannot show a product on your page for id

but one. I think the problem is how to get your action show

to work.

If so, let me explain ...

Rails is resource based , which means that everything you do / create should be centered around some resource (object). The problem is that a lot of people are unaware of this and hence obscure the structure of the controller for no reason:

enter image description here

Above is a typical "CRUD" routing structure for Rails based resources. This should demonstrate how Rails would normally be built - around resources.

-

Plus, Rails is built on MVC programming pattern

- which means you need to use your controller to populate a series of data objects for use in your application.

To this end, if you are loading a resource and want to fill it with resourceful information of another object - you need to make sure that you set up the data objects so that you can view them correctly, which either means passing data through your routes or using a persistent data type. for example cookies

or sessions


You have a problem to pass the product id to your controller somehow . How I would do it: nested resources ):

#config/routes.rb
resources :offers do
   resources :products #-> domain.com/offers/2/products
end

      

This will give you the ability to load a controller products

with variables params[:id]

for the product, and params[:offer_id]

for your offer

made available:

#app/controllers/products_controller.rb
Class ProductsController < ApplicationController
  def show
      @offer = Offer.find params[:offer_id]
      @product = Product.find params[:id]
  end
end

      

+6


source







All Articles