I have a user model with Paperclip for avatars and I need to be able to return the image_url for each size (small, medium, large) using RABL.
In mongoid model i would simply do self.avatar(:original) but now nothing works, I just get an empty response in the attachment
"user" : {
"id" : "50b204e10eae9c55fa000028",
"paperclip::attachment" : {},
"name" : "My Name"
}
/models/user.rb
has_mongoid_attached_file :avatar,
:styles => {
:original => ['1000x1000>', :jpg],
:small => ['64x64#', :jpg],
:medium => ['250x250', :jpg],
:large => ['500x500>', :jpg]
}
/views/posts/base.json.rabl
child :user do
attributes :id, :name
child :avatar do
attributes :original
end
end
Try this:
child :user do
attributes :id, :name
node :avatar_original do |u|
u.avatar(:original)
end
end
Related
I have method called check_field, purpose of this method is for checking is there multiple value when input form.
I was think maybe I can check with multiple array on rails. I found some code on this link to check duplicate value inside array. So, I implement that method (difference) on my model
, but I got stuck when implement to my Model, the methot won't called.
NoMethodError (undefined method `difference' for ["vvvv", "vvvv", "xxxxxxxxx", "xxxxxxxxx"]:Array):
here my Code.
class Model < ApplicationRecord
has_many :child_models, -> { where(active: true) }, :foreign_key => :model_id, :dependent => :destroy
accepts_nested_attributes_for :child_models, :allow_destroy => false
before_validation :check_field, :before => [:create]
def check_field
all_field = Array.new
child_models.each do |data|
all_field << data.field
end
uniq_field = all_field.uniq
result = uniq_field - all_field.difference(uniq_field)
errors.add(:field, "Field must be Different")
end
def difference(other)
h = other.each_with_object(Hash.new(0)) { |e,h| h[e] += 1 }
reject { |e| h[e] > 0 && h[e] -= 1 }
end
end
the field that I want to validate is on child_models,
class ChildModel < ApplicationRecord
validates :field, presence: { message: "Field" + I18n.t("sys_err_is_required"), :if => :active?, :scope => [:active] }, :uniqueness => { :message => 'Field is already exist', :if => :active?, :scope => [:active], :case_sensitive => false }
end
I was try to put check_field method on ChildModel, it didn't work, because the parameters can be read on Model class.
so then any solution for this case?
thanks.
you should use self.difference to call your method, because it is a classmethod. see https://dev.to/adamlombard/ruby-class-methods-vs-instance-methods-4aje
...
result = self.difference(uniq_field)
I'm using react for the client side and rails for the server.
When trying to link the post to its username I get 'undefined'.
If I try user={post.user_id} to get the user_id, it works fine, but I want to show the username.
PostList.jsx
{posts.map((post) => (
<>
<Post
key={post.id}
title={post.title}
content={post.content}
user={post.user.username}
id={post.id}
getPosts={getPosts} />
</>
Post.jsx
const Post = ({title, content, user, id, getPosts}) => {
return (
<div className='post-container'>
<div className='post-header'>
<div className='post-title-user'>
<h2>{title}</h2>
<span>Posted by: #{user}</span>
</div>
</div>
<p>{content}</p>
</div>
)
}
export default Post
schema.rb
create_table "posts", force: :cascade do |t|
t.string "title"
t.text "content"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "user_id", null: false
t.index ["user_id"], name: "index_posts_on_user_id"
end
create_table "users", force: :cascade do |t|
t.string "username"
t.string "password_digest"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
user.rb
class User < ApplicationRecord
has_secure_password
has_many :posts
end
post.rb
class Post < ApplicationRecord
belongs_to :user
end
I think you should use active_model_serializers gem
Step1: add gemfile gem 'active_model_serializers'
Step2: bundle
Step3: rails g serializer post
In posts_controller.rb
class PostsController < ApplicationController
def index
posts = Post.all
render json: {
message: 'Get posts',
data: ActiveModel::Serializer::CollectionSerializer.new(posts, each_serializer: PostSerializer)
}
end
end
In post_serializer.rb
class PostSerializer < ActivieModel::Serializer
attributes :id, :title, :content, :username
def username
#You try byebug and check object
object.username
end
end
I have two models TeamMember and ProjectRequest.
A TeamMember can have one ProjectRequest, that is why I created the following Eloquent relationship on TeamMember:
class TeamMember extends Model {
//
protected $table = 'team_members';
protected $fillable = ['project_request_id'];
// Relations
public function projectTeam() {
return $this->hasOne('\App\Models\ProjectRequest', 'project_request_id');
}
}
In my Controller I want to query both tables, however it returns the failure message.
What is important to know is that $request->projectTeam is an array of emails, looking like this:
array:2 [
0 => "mv#something.com"
1 => "as#something.com"
]
Meaning that I need to bulk insert into team_members table the project_request_ id for each team member where the emails are in the array.
How can I do that in the right way? The following is my attempt:
public function createProjectTeam(Request $request){
try {
$title = $request->projectTitle;
$TeamMember = $request->projectTeam;
$projectRequest = ProjectRequest::create(['project_title' => $title]);
$projectRequestId = $projectRequest->id;
$projectTeam = $this->teamMembers->projectTeam()->create(['project_request_id'=> $projectRequestId])->where('email', $TeamMember);
//$projectTeam = TeamMember::createMany(['project_request_id' => $projectRequestId])->where($TeamMember);
//dd($projectTeam);
return $projectRequest.$projectTeam;
} catch(\Exception $e){
return ['success' => false, 'message' => 'project team creation failed'];
}
}
There are a few things you can do.
Eloquent offers a whereIn() method which allows you to query where a field equals one or more in a specified array.
Secondly, you can use the update() method to update all qualifying team members with the project_request_id:
public function createProjectTeam(Request $request)
{
try {
$projectRequest = ProjectRequest::create(['project_title' => $request->projectTitle]);
TeamMember::whereIn('email', $request->projectTeam)
->update([
'project_request_id' => $projectRequest->id
]);
return [
'success' => true,
'team_members' => $request->projectTeam
];
} catch(\Exception $e) {
return [
'success' => false,
'message' => 'project team creation failed'
];
}
}
I hope this helps.
I need to update the database table according to the edited data.
controller
public function update(Request $request)
{
$subscriptionplan = SubscriptionPlan::find($request->id);
$subscriptionplan->update($request->all());
return back();
}
But nothing happens when I submit the form. When I use dd($request->all()); at the beginning of the function, it correctly shows the edited data as follows.
array:10 [▼
"_method" => "patch"
"_token" => "gOCL4dK6TfIgs75wV87RdHpFZkD7rBpaJBxJbLHF"
"editname" => "SUP_EVA_001"
"editdesc" => "des"
"editprice" => "1000.050"
"editlimit" => "1"
"editperunit" => "20.000"
"editexceedunit" => "30.000"
"productid" => "1"
"id" => "1"
]
But database has not been updated.
My table name is Table: subscription_plans and model is SubscriptionPlan
These are the table columns:
protected $fillable = [
'name',
'description',
'price',
'usage_limit',
'charge_per_unit',
'charge_per_unit_exceed',
'is_limit_exceed_considered',
'product_id'
];
Any idea on how to solve it or what I have done wrong?
If your solution did not work, try the 1by1 like this.
public function update(Request $request)
{
$subscriptionplan = SubscriptionPlan::find($request->id);
$subscriptionplan->_method = $request->_method;
$subscriptionplan->_token = $request->_token;
$subscriptionplan->editname = $request->editname;
$subscriptionplan->editdesc = $request->editdesc;
$subscriptionplan->editprice = $request->editprice;
$subscriptionplan->editlimit = $request->editlimit;
$subscriptionplan->editperunit = $request->editperunit;
$subscriptionplan->editexceedunit = $request->editexceedunit;
$subscriptionplan->productid = $request->productid;
$subscriptionplan->save();
return back();
}
In order for Laravel to automatically fill the model attributes, the indexes of the array passed to the fill method must correspond to your model attributes names.
Also, instead of
$subscriptionplan->update($request->all());
Use
$subscriptionplan->fill($request->all());
Then save the subscription plan with $subscriptionplan->save();
I'm calling an array of recommended products (based on the predictor-gem) and want to exclude the products of the current_user from that set. I think that I'm using the proper condition for it (" != ?") but just not in the correct way. #products_rec should give that final array.
Here's the specific code in my product_controller.rb:
recommender = ProductRecommender.new
products = current_user.products
#product_rec = (recommender.similarities_for("product-#{#product.id}")).map {|el| el.gsub(/(.*\-)[^\d]*/, "")}
#products_rec = Product.find(#product_rec, :conditions => ["id != ?", products.id])
and here's my model, product.rb:
class Product < ActiveRecord::Base
include Reviewing
include PublicActivity::Model
tracked
extend FriendlyId
friendly_id :name, use: [:slugged, :finders]
belongs_to :category
belongs_to :benefit
has_many :subscriptions
has_many :users, through: :subscriptions
has_many :benefits
has_many :projects, through: :benefits
belongs_to :user
validates :name, presence: true, length: { maximum: 200 }
validates :gtin, presence: false
validates :content, presence: false, length: { maximum: 2000 }
validates :video, presence: false
validates :tag, presence: false
validates :project, presence: false
validates :category, presence: false
validates :user, presence: false
has_attached_file :image, :styles => { :medium => "680x300>", :thumb => "170x75>" }
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
end
I want to exclude the products from the current_user, based on the users through subscriptions (see model).
How can I get this to work, any ideas?
Final code:
Based on the answer of #Humza, I've added the following working code to my product_controller.rb:
recommender = ProductRecommender.new
products = current_user.products.select("id")
#product_rec = (recommender.similarities_for("product-#{#product.id}")).map {|el| el.gsub(/(.*\-)[^\d]*/, "")}
#products_rec_array = Product.find(#product_rec)
#products_rec = Product.where(id: #products_rec_array).where.not(id: products)
To find products with id not in array, you must do this:
array = current_user.products.pluck(:id)
Product.where('id NOT IN (?)', array) # '?' is surrounded by paranthesis
But since a product belongs to a user, you can simply do
Product.where('user_id != ?', current_user.id)
You can also use the not method like so:
Product.where.not(id: array)
Product.where.not(user_id: current_user.id)
Edit:
If you want the base products to be from some other list, this can help:
base_product_ids = some_list.map(&:id) # assuming this is an Array
Product.where(id: base_product_ids).where.not(user_id: current_user.id)
If some_list was an ActiveRecord::Relation, you could have simply done:
some_list.where.not(user_id: current_user.id)