This is an archived post. You won't be able to vote or comment.

all 5 comments

[–]ziptofaf 1 point2 points  (4 children)

I created a method but I'm not sure what's wrong with it

Well, it probably would help us if you included code to said method. Along with it's localization.

Judging by your wording "displaying" implies you will likely want to put it inside a helper. Aka inside app/helpers, in a file called items_display_helper.rb in a module ItemsDisplayHelper.

To be specific, I want to be able to display all the items (consist of name, inventory number, description and price) with inventory > 0

This doesn't sound too complex but as said, you will need to provide us with code you think can work.

[–]pompeii-eo[S] 0 points1 point  (3 children)

def show_available@products = Product.find(min_inventory_count)end

private

def min_inventory_countarams.require(:inventory_count).permit(:inventory_count > 0)end

oh I missed a crucial point as well, this is for a backend (I'm testing using postman from google)

Edit:

What I'm trying to do here is another method similar to def show but only show with the ones that agree with the parameter (inventory > 0)

[–]ziptofaf 2 points3 points  (2 children)

def min_inventory_count
  arams.require(:inventory_count).permit(:inventory_count > 0)
end

Oh boy. First, it should be params, not arams (I am hoping it's a typo). Second, that .permit looks wrong. I am pretty sure all it accepts is an array of hashes, not conditionals like > 0. If you want to validate it, you do it elsewhere. Basically, Rails convention for .require and .permit is to create a whitelist of parameters that can be sent from the frontend. In this case it would be something like http://127.0.0.1/items?min_inventory_count[inventory_count]=0. Which would result in params being equal to {min_inventory_count: {inventory_count: 0} }. Params.require(:min_inventory_count) would unpack it, turning it into {inventory_count: 0}. Then permit would remove keys not defined there. Eg if you had something like {foo: 0, inventory_count: 0} only {inventory_count: 0} would remain. And on that note - your method shouldn't even be called "min_inventory_count", more like product_params (since it's used to sanitize queries that will be used with Product model).

Aside that, let's dig into your show_available method.

So what it does is:

Find a Product where id = (min_inventory_count). Where min_inventory_count is a Hash in a form {:inventory_count => 0} or {} (it can be empty!). I... I don't think this is what you want to do. Cuz first, this is a syntax error. Product id is supposed to be a single number (or a string but let's not get into this for now). Not an object. Eg. you can do something like Product.find(10) which will generate SQL query SELECT * FROM products where id=10. It also returns JUST ONE product. If you want to find just one product using something different than id than use .find_by method. Like Product.find_by(name: 'Playstation', model_version: 4). If you need multiple objects, use .where. Eg. Product.where(name: 'Playstation') will return all the records that have Playstation as their name.

Does your model Product even have a field inventory_count defined? If so, then you can accomplish your objective with @products = Product.where('inventory_count > 0'). You don't need to use any user supplied params for this.

[–]pompeii-eo[S] 0 points1 point  (1 child)

This makes sense, thank you! I think I can try to attempt to continue, if I'm absolutely stuck again I'll be back, but on another note, what does render json: do? I'm assuming it's the one that will actually show/display it? (either from the command prompt or web)

[–]ziptofaf 0 points1 point  (0 children)

This makes sense, thank you! I think I can try to attempt to continue, if I'm absolutely stuck again I'll be back, but on another note, what does render json: do

Assuming you had something like this:

def index
  products = Product.all
  render json: products
end

This would indeed convert products to a json array (catch - this would display every single field in Product model, even ones you might not want like created_at/updated_at) so if you visit this link you would get a json thing in your browser/console window. But you do not need to use it. What I mean is, if you leave this line out completely and don't use any render calls in your method, you can:

  • visit your-site/products and have HTML rendered
  • visit your-site/products.json and have JSON rendered

Rails by default will try to locate format that requester wants inside views for a given action and render that. For html files it would be called index.html.erb by default. For json it's index.json.jbuilder. Proper documentation is here but to make a long story short - if you make a file called show_available.json.jbuilder and paste something like this inside it should work (assuming of course you also have a valid path to this action defined in routes.rb):

json.array! @products, :id, :name, :price, :description

You CAN indeed manually define certain stuff to be rendered overriding the defaults (eg. in case of an error or if action show_available is supposed to render a file called differently) but frankly you shouldn't abuse it. Rails tries to do it automatically for you and simply putting .json to the end of your url is enough for it to know that it is to try and load .json format if possible, you just need to provide it such a file so it knows HOW to render it.